Migration vers l'arrière avec Django South

217

Ok, donc cela semble être une chose vraiment stupide à demander, et je suis sûr que je manque quelque chose quelque part.

Comment effectuez-vous une migration vers l'arrière en utilisant South sur Django?

J'ai donc peaufiné mes modèles, créé une migration avec schemamigration, exécuté la migration avec migrate, et maintenant je réalise que ce n'est pas tout à fait ce que je voulais et je le veux comme avant.

À moins de modifier manuellement les tables db et de supprimer les fichiers de migration, comment dois-je procéder pour annuler la migration? Je trouve des références à des migrations en arrière utilisant South via Google, mais je n'ai pas encore trouvé d'exemple de code solide pour cela.

Quelqu'un peut-il aider?

Ruiwen
la source
bonne question!!
Marshall X

Réponses:

335

Vous devez déterminer le numéro de la migration juste avant celui que vous souhaitez annuler.

Votre application doit avoir un répertoire de migrations, avec des fichiers nommés comme

0000_initial.py
0001_added_some_fields.py
0002_added_some_more_fields.py
0003_deleted_some_stuff.py

Normalement, lorsque vous exécutez ./manage.py migrate your_app, South exécute toutes les nouvelles migrations, dans l'ordre. (Il examine les tables de la base de données pour décider lesquelles sont «nouvelles»).

Cependant, vous pouvez également spécifier toute migration par numéro, et South fera migrer votre base de données, vers l'avant ou vers l'arrière , pour l'amener à ce point. Donc, avec les fichiers d'exemple ci-dessus, si vous avez déjà migré jusqu'à 0003 et que vous vouliez exécuter 0003 en sens inverse (l'annuler, en fait), vous exécuteriez

./manage.py migrate your_app 0002

South examinerait la base de données, se rendrait compte qu'elle a déjà exécuté 0003 et déterminerait qu'elle doit exécuter la migration inverse pour 0003 afin de revenir à 0002.

Ian Clelland
la source
1
Malheureusement, lorsque vous créez votre prochaine migration, elle ne saute pas celles entre les deux, vous devez donc simplement les migrer à nouveau plus tard. On dirait qu'il pourrait y avoir une meilleure façon.
mlissner
44
@mlissner Si vous voulez vraiment, après avoir restauré la base de données, allez dans le dossier migrations de l'application donnée (dans l'exemple ci-dessus your_app / migrations) et supprimez la migration indésirable
Josh Russo
1
Exactement - le Sud ne saute jamais les migrations; il s'attend à ce que les fichiers de 0001-nnnn représentent un ensemble cohérent de migrations, pour n'importe quelle valeur de nnnn. Si ce n'est pas le cas, vous devez réorganiser ou supprimer vous-même les infractions.
Ian Clelland
217

Juste au cas où quelqu'un (comme moi) se demanderait comment revenir de l'initiale (0001) :

django-admin.py migrate some_app zero

production:

Running migrations for some_app:
 - Migrating backwards to zero state.
 < some_app:0001_initial

"zéro" est un état spécial avant toute migration.

Référence: http://south.aeracode.org/docs/commands.html

Ctrl-C
la source
6
Quelqu'un a exécuté migrate 0001 --fake, et c'était le seul moyen d'exécuter 0001 en arrière. Merci!
jmanning2k
1
Réponse très importante, je me demandais pourquoi ça migrate 0000ne fonctionnait pas. À propos de la fausse migration, oui, vous en aurez peut-être besoin, si vous devez par exemple annuler uniquement la migration initiale (probablement erronée), mais l'historique de la migration pense que cette migration n'a jamais eu lieu.
Tomasz Gandor
3

Ajoutez un nom de migration à la fin des paramètres:

./manage.py migrate app-name 00xx-migration-name
Jerzyk
la source
2
C'est OK, et je l'ai fait avant, mais c'est beaucoup de dactylographie / collage. Le simple nombre "d'état" - dans ce cas 00xx- est suffisant. Lorsque vous améliorez et testez une migration, vous pouvez avoir les deux commandes dans l'historique: en avant (sans argument), en arrière avec le numéro d'état précédent.
Tomasz Gandor