HOWTO · Django

Réinitialiser les migrations dans Django

Apprenez à réinitialiser les migrations dans Django

Sur cette page

Les migrations Django sont des instructions versionnées qui modifient le schéma d’une base de données. Django enregistre également dans la base les migrations qui ont été appliquées. « Réinitialiser les migrations » peut donc désigner plusieurs opérations différentes : ramener une application à une migration connue, annuler les migrations de cette application, vider les lignes tout en conservant le schéma, ou remplacer une base de développement. Choisissez l’opération en fonction du résultat souhaité ; supprimer les fichiers de migration ne remplace aucune de ces opérations.

Avant toute opération destructive, vérifiez quel fichier de paramètres et quelle base de données votre commande utilisera, consultez l’état actuel des migrations avec python manage.py showmigrations et effectuez une sauvegarde que vous pourrez restaurer si les données sont importantes. Dans les commandes ci-dessous, AppName est un espace réservé pour le libellé de l’application, par exemple blog ; utilisez le libellé reconnu par Django, qui n’est pas nécessairement le chemin complet du paquet Python.

Ce que change une réinitialisation des migrations

Un fichier de migration décrit des opérations sur le schéma et peut aussi déplacer ou transformer des données. La table des migrations enregistre les noms des migrations appliquées. Le retour en arrière d’une application modifie l’état de son schéma enregistré en exécutant les opérations inverses disponibles ; il ne réécrit pas les fichiers de migration. La commande flush vide les lignes tout en conservant le schéma et l’historique des migrations. Le remplacement d’une base de développement supprime ses données et ses enregistrements de migration ; il faut ensuite appliquer à nouveau les migrations.

Ces opérations n’ont pas la même portée. Pour annuler une modification récente du schéma, ciblez une migration antérieure. Si l’application ne doit avoir aucune migration appliquée, ciblez zero. Si vous souhaitez seulement vider les données de l’application, utilisez flush. Si une base locale peut être supprimée et que vous souhaitez la reconstruire entièrement, remplacez cette base puis relancez les migrations du projet. Ne supprimez pas les fichiers de migration pour donner l’impression que la base a été réinitialisée : les environnements existants et les autres membres de l’équipe dépendent toujours de ces fichiers, qui définissent l’historique partagé des migrations.

Revenir à une migration antérieure pour une application

Repérez la migration cible avec showmigrations AppName ou consultez les fichiers de migration de l’application. Utilisez ensuite python manage.py migrate AppName 0004 pour ramener l’application à la migration 0004 ; remplacez les espaces réservés par le libellé réel de l’application et la migration cible. Vous pouvez utiliser un nom de migration tel que initial à la place d’un numéro si c’est le nom affiché pour cette migration.

La cible correspond à l’état obtenu après cette migration : les migrations ultérieures de l’application sont donc annulées. Les opérations inverses peuvent modifier ou supprimer des colonnes, ainsi que les données qu’elles contiennent. Django peut également devoir ajuster les migrations dépendantes pour préserver la cohérence du graphe des migrations. Avant d’exécuter la commande, examinez les changements prévus et vérifiez quelle base est sélectionnée par les paramètres actifs, surtout si d’autres applications dépendent de celle-ci.

Un petit extrait Python permet de rendre explicite le modèle de commande avant de l’adapter à votre projet. Remplacez l’application et la migration cibles de l’exemple par les valeurs de votre propre liste de migrations.

Exécutez cet exemple :

Le code et les libellés ou sorties affichés dans cette section restent en anglais.

app_label = "blog"
target_migration = "0004"
print(f"python manage.py migrate {app_label} {target_migration}")
python manage.py migrate blog 0004

Cet extrait affiche un modèle de commande ; il ne se connecte pas à Django et ne modifie aucune base de données.

Remettre une application à zéro

Pour annuler toutes les migrations d’une application, utilisez python manage.py migrate AppName zero. Cette opération concerne l’état des migrations et les opérations sur le schéma de cette application ; elle ne réinitialise pas toute la base de données. Selon les migrations et les relations concernées, leur annulation peut supprimer des tables ou des données et nécessiter également l’annulation de migrations dépendantes. Si le résultat est incertain, examinez d’abord les effets prévus dans un environnement jetable.

Ne supprimez pas ensuite les fichiers de migration de l’application dans un projet partagé ou déployé. Django utilise ces fichiers comme historique pour construire le schéma dans les autres bases de données. Si l’équipe décide volontairement de regrouper ou de remplacer l’historique des migrations, coordonnez une procédure distincte de maintenance des migrations dans tous les environnements ; ne considérez pas zero comme une autorisation à effacer cet historique.

Réinitialiser une base de développement

Pour vider une base tout en conservant ses tables et les migrations appliquées, exécutez python manage.py flush. Cette commande supprime les données de la base et réinitialise les séquences, mais conserve le schéma et les enregistrements de migration. C’est généralement le bon choix si vous souhaitez recharger des fixtures ou repartir avec des données d’application vierges ; cette commande ne reconstruit pas le schéma à partir des fichiers de migration.

Pour reconstruire entièrement une base locale, arrêtez les processus qui l’utilisent, vérifiez que les paramètres actifs pointent vers une base de développement jetable, puis remplacez cette base en suivant la procédure adaptée à son moteur. Avec SQLite, il peut s’agir de supprimer le fichier local de la base. Avec une base de données serveur, il faut généralement supprimer puis recréer une base de développement avec les identifiants appropriés. Exécutez ensuite python manage.py migrate pour créer le schéma et appliquer les migrations du projet. Les commandes de suppression varient selon le moteur de base de données : suivez la procédure documentée pour celui que vous utilisez et ne réutilisez jamais en production une commande de réinitialisation destinée au développement sans plan de restauration explicite.

Supprimer les fichiers de migration et en créer de nouveaux à partir des modèles actuels constitue une réécriture distincte et coordonnée de l’historique. Cette opération peut casser les installations déployées, les copies de travail des autres membres de l’équipe et les dépendances entre migrations, même si une base locale a été reconstruite avec succès. Conservez les fichiers de migration dans le contrôle de version et créez de nouvelles migrations pour les modifications ordinaires des modèles.

Gérer prudemment les migrations irréversibles

Certaines migrations ne peuvent pas être annulées parce que leurs opérations détruisent des informations ou ne définissent aucune opération inverse. Django peut interrompre un retour en arrière avec IrreversibleError. L’état de la base après l’échec dépend du caractère atomique de la migration et du comportement transactionnel de la base ; un retour en arrière peut avoir des effets partiels. Ne supposez pas qu’une commande de retour en arrière restaurera les données supprimées ou transformées.

Avant de tenter un retour en arrière, examinez les opérations de la migration et sauvegardez les données à conserver. Testez ce retour en arrière sur une copie récente de la base, vérifiez le schéma obtenu et les enregistrements importants, puis confirmez à nouveau l’environnement cible juste avant l’opération. Si la migration est irréversible, restaurez une sauvegarde appropriée ou écrivez délibérément une migration vers l’avant qui mène à l’état souhaité ; ne supprimez pas manuellement des enregistrements de migration pour masquer le décalage.