Повторить миграцию данных Django

Как перезапустить миграцию данных на Django 1.8+? Если это уместно, моя миграция пронумерована 0011_my_data_migration.py и является последней миграцией.

2 ответа

Возвратитесь к миграции перед тем, который вы хотите повторить.

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

Затем перезапустите миграцию.

./manage.py migrate your app 0011_my_data_migration

Затем вы можете подделать предыдущую миграцию, которую вы выполнили. В вашем случае вы сказали, что 0011 был последним, поэтому вы можете пропустить этот этап.

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

Обратите внимание, что в зависимости от состояния вашей базы данных и содержимого миграции повторная миграция, например, может привести к ошибкам. Обратите внимание на предупреждение в документах о опции --fake:

Это предназначено для продвинутых пользователей для непосредственного управления текущим состоянием миграции, если они вручную применяют изменения; следует предупредить, что использование --fake сопряжено с риском переноса таблицы состояний миграции в состояние, в котором потребуется ручное восстановление, чтобы миграция выполнялась правильно.


Ответ Alasdair дает об этом отказ от ответственности, но возврат к предыдущей миграции только безопасен, если ваша миграция является идемпотентной, что означает, что вы можете запускать ее несколько раз без побочных эффектов, таких как дубликаты данных. Большинство людей не пишут свои миграции таким образом, но это хорошая практика.

У вас есть два способа сделать этот процесс безопасным:

  • Сделайте свои миграции данных идемпотентными. Это означает, что любые созданные данные либо повторно используются (например, с помощью метода Model.objects.get_or_create()), либо удаляются и воссоздаются. Повторное использование - лучший вариант, так как удаление и повторное создание изменят индексы и последовательности баз данных.
  • Сделать обратную миграцию данных. Вы можете сделать это, передав 2 функции в migrations.RunPython(). Например, если у вас есть migrations.RunPython(add_countries), вы должны изменить это на migrations.RunPython(add_countries, remove_countries) и удалить любые соответствующие страны во второй функции.

Если вы выберете вариант № 2, вы запустите:

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

Если вы хотите сделать один лайнер, чтобы его можно было использовать снова и снова:

./manage.py migrate --fake yourapp 0010_my_previous_data_migration && ./manage.py migrate yourapp 0011_my_data_migration

licensed under cc by-sa 3.0 with attribution.