J'ai effectué une migration qui a ajouté une nouvelle table et je souhaite la rétablir et supprimer la migration, sans créer de nouvelle migration.
Comment fait-on ça? Existe-t-il une commande pour annuler la dernière migration et puis-je simplement supprimer le fichier de migration?
django
django-migrations
Ronen Ness
la source
la source
migrate
commande vous permet./manage.py migrate my_app zero
de désappliquer toutes les migrations de l'application.'0010_previous_migration'
, je ne sais pas pourquoi vous verriez ce comportement.La réponse d'Alasdair couvre les bases
./manage.py showmigrations
migrate
en utilisant le nom de l'application et le nom de la migrationMais il convient de souligner que toutes les migrations ne peuvent pas être inversées. Cela se produit si Django n'a pas de règle pour effectuer l'inversion. Pour la plupart des modifications par lesquelles vous avez effectué automatiquement les migrations
./manage.py makemigrations
, l'annulation sera possible. Cependant, les scripts personnalisés devront avoir à la fois un avant et un arrière écrit, comme décrit dans l'exemple ici:https://docs.djangoproject.com/en/1.9/ref/migration-operations/
Comment faire une inversion sans opération
Si vous avez eu une
RunPython
opération, vous souhaiterez peut-être simplement annuler la migration sans écrire un script d'inversion logiquement rigoureux. Le hack rapide suivant de l'exemple de la documentation (lien ci-dessus) le permet, en laissant la base de données dans le même état qu'elle était après l'application de la migration, même après l'avoir inversée.Cela fonctionne pour Django 1.8, 1.9
Mise à jour: Une meilleure façon d'écrire ceci serait de la remplacer
lambda apps, schema_editor: None
parmigrations.RunPython.noop
dans l'extrait ci-dessus. Ce sont deux fonctionnellement la même chose. (crédit aux commentaires)la source
RunPython.noop
place d'un lambda en ligne ou d'un équivalent: docs.djangoproject.com/en/1.8/ref/migration-operations/…migrations.RunPython(forwards_func, migrations.RunPython.noop)
. Besoin de vérifier cela fonctionnellement. Cela devrait être ajouté en tant que réponse ou modification à celle-ci un jour.Voici ma solution, car la solution ci-dessus ne couvre pas vraiment le cas d'utilisation, lorsque vous utilisez
RunPython
.Vous pouvez accéder à la table via l'ORM avec
Vous pouvez donc interroger les tables et supprimer les entrées qui vous concernent. De cette façon, vous pouvez modifier en détail. Avec les
RynPython
migrations, vous devez également prendre soin des données qui ont été ajoutées / modifiées / supprimées. L'exemple ci-dessus montre uniquement comment vous accédez à la table via Djang ORM.la source
django.db.utils.ProgrammingError: relation "<relation name>" already exists
ci, j'ai donc fait unmigrate --fake
qui est faux, alors j'ai essayé de revenir en arrière, puis j'ai eu unpsycopg2.ProgrammingError: relation "<other <relation name>" does not exist
MERCIL'autre chose que vous pouvez faire est de supprimer la table créée manuellement.
Parallèlement à cela, vous devrez supprimer ce fichier de migration particulier. De plus, vous devrez supprimer cette entrée particulière dans la table django-migrations (probablement la dernière dans votre cas) qui correspond à cette migration particulière.
la source
Ne supprimez le fichier de migration qu'après la réversion. J'ai fait cette erreur et sans le fichier de migration, la base de données ne savait pas quoi supprimer.
Supprimez le fichier de migration. Une fois la migration souhaitée dans vos modèles ...
la source
Je l'ai fait dans 1.9.1 (pour supprimer la dernière ou la dernière migration créée):
rm <appname>/migrations/<migration #>*
exemple:
rm myapp/migrations/0011*
connecté à la base de données et exécuté ce SQL (postgres dans cet exemple)
delete from django_migrations where name like '0011%';
J'ai ensuite pu créer de nouvelles migrations qui ont commencé avec le numéro de migration que je venais de supprimer (dans ce cas, 11).
la source
Cette réponse est pour des cas similaires si la première réponse d'Alasdair n'aide pas . (Par exemple, si la migration indésirable est créée à nouveau à chaque nouvelle migration ou si elle se trouve dans une migration plus importante qui ne peut pas être annulée ou si la table a été supprimée manuellement.)
TL; DR : Vous pouvez supprimer quelques dernières migrations annulées (confuses) et en faire une nouvelle après avoir corrigé les modèles . Vous pouvez également utiliser d'autres méthodes pour le configurer afin de ne pas créer de table par commande migrate. La dernière migration doit être créée pour correspondre aux modèles actuels .
Cas où quelqu'un ne veut pas créer une table pour un modèle qui doit exister:
A) Aucune telle table ne devrait exister dans aucune base de données sur aucune machine et aucune condition
class Meta: abstract = True
B) La table est créée rarement, par autre chose ou manuellement d'une manière spéciale.
class Meta: managed = False
La migration est créée, mais jamais utilisée, uniquement dans les tests. Le fichier de migration est important, sinon les tests de base de données ne peuvent pas s'exécuter, à partir d'un état initial reproductible.
C) La table est utilisée uniquement sur certaines machines (par exemple en développement).
class Meta: managed = some_switch
.D) Le projet utilise plusieurs bases de données
settings.DATABASES
allow_migrate
afin de différencier les bases de données où la table doit être créée et où pas.La migration est créée dans tous les cas A), B), C), D) avec Django 1.9+ (et seulement dans les cas B, C, D avec Django 1.8), mais appliquée à la base de données uniquement dans les cas appropriés ou peut-être jamais si nécessaire. Les migrations ont été nécessaires pour exécuter des tests depuis Django 1.8. L'état actuel complet pertinent est enregistré par les migrations même pour les modèles avec managed = False dans Django 1.9+ pour être possible de créer une clé étrangère entre les modèles gérés / non gérés ou pour rendre le modèle géré = True plus tard. (Cette question a été écrite à l'époque de Django 1.8. Tout ici devrait être valable pour les versions entre 1.8 et la 2.2 actuelle.)
Si la dernière migration n'est pas (ou n'est pas) facilement réversible, il est possible de faire prudemment (après la sauvegarde de la base de données) un faux rétablissement
./manage.py migrate --fake my_app 0010_previous_migration
, supprimez la table manuellement.Si nécessaire, créez une migration fixe à partir du modèle fixe et appliquez-la sans modifier la structure de la base de données
./manage.py migrate --fake my_app 0011_fixed_migration
.la source
Si vous rencontrez des problèmes lors de l'annulation de la migration et que vous l'avez en quelque sorte gâché, vous pouvez effectuer des
fake
migrations.Pour la version django <1.7, cela créera une entrée dans le
south_migrationhistory
tableau, vous devez supprimer cette entrée.Vous pourrez désormais revenir facilement à la migration.
PS: J'ai été coincé pendant beaucoup de temps et j'ai effectué une fausse migration, puis revenir en arrière m'a aidé.
la source