web-dev-qa-db-fra.com

Réexécutez une Django

Comment relancer une migration de données sur Django 1.8+? Le cas échéant, ma migration est numérotée 0011_my_data_migration.py et est la dernière migration.

32
davidhwang

Revenez à la migration avant celle que vous souhaitez réexécuter.

./manage.py migrate --fake yourapp 0010_my_previous_data_migration

Relancez ensuite la migration.

./manage.py migrate yourapp 0011_my_data_migration

Ensuite, vous pouvez revenir à la migration la plus récente que vous avez exécutée. Dans votre cas, vous avez dit que 0011 était le dernier, vous pouvez donc sauter cette étape.

./manage.py migrate --fake yourapp 0014_my_latest_data_migration

Notez que selon l'état de votre base de données et le contenu des migrations, la réexécution d'une migration comme celle-ci peut provoquer des erreurs. Notez l'avertissement dans la documentation sur le --fake option:

Ceci est destiné aux utilisateurs avancés pour manipuler directement l'état de migration actuel s'ils appliquent manuellement des modifications; être averti qu'en utilisant --fake court le risque de placer la table d'état de migration dans un état où une récupération manuelle sera nécessaire pour que les migrations s'exécutent correctement.

73
Alasdair

La réponse d'Alasdair donne un avertissement à ce sujet, mais simuler une migration vers la précédente n'est sûr que si votre migration est idempotente, ce qui signifie que vous pouvez l'exécuter plusieurs fois sans effets secondaires comme des données en double. La plupart des gens n'écrivent pas leurs migrations de cette façon, mais c'est une bonne pratique.

Vous avez deux options pour sécuriser ce processus:

  1. Rendez vos migrations de données idempotentes. Cela signifie que toutes les données créées sont soit réutilisées (comme avec la méthode Model.objects.get_or_create()), soit supprimées et recréées. Réutilisé est la meilleure option, car la suppression et la recréation modifieront les index et les séquences de la base de données.
  2. Effectuez des migrations de données inversées. Vous pouvez le faire en passant 2 fonctions à migrations.RunPython(). Par exemple, si vous avez migrations.RunPython(add_countries), vous devez changer cela en migrations.RunPython(add_countries, remove_countries) et supprimer tous les pays pertinents dans la deuxième fonction.

Si vous choisissez l'option # 2, vous exécutez:

./manage.py migrate yourapp 0010_my_previous_data_migration
./manage.py migrate yourapp 0011_my_data_migration

Si vous vouliez en faire une doublure pour pouvoir l'utiliser encore et encore:

./manage.py migrate yourapp 0010_my_previous_data_migration && ./manage.py migrate yourapp 0011_my_data_migration
7
Jordan