Перемещение между миграциями
В этой статье мы углубимся в мир миграций Django. Если вы не знакомы с миграциями — вот статья о них.
Мы рассмотрим несколько инструментов при работе с миграциями. С их помощью вы сможете полностью контролировать процесс миграций без потери данных — накатывать новые миграции и чинить старые.
Миграции — это записи в БД
Миграции — это не только файлы в папке migrations
. Это ещё и таблица в базе данных. В этой таблице есть записи, какие миграции уже были выполнены, а какие — нет. Хранятся они примерно так:
Django даже позволяет туда “заглянуть”:
$ python manage.py showmigrations
Эта команда показывает какие из миграций уже применены к БД, т.е. для каких миграций уже запускали migrate
. Они помечены крестиком:
appname
[X] 0001_initial
[X] 0002_new_model
[X] 0003_auto_20190805_1906
[X] 0004_new_field
[X] 0005_auto_20190805_1920
[ ] 0006_auto_20190807_1545
[ ] 0007_auto_20190808_1301
[ ] 0008_auto_20190808_1314
Django показала все миграции, которые она нашла в папке migrations
приложении appname
. Крестиком помечены те, которые есть у неё в базе данных. Если вы запустите python manage.py migrate
, выполнятся 3 оставшиеся миграции: 0006
, 0007
и 0008
.
Управление миграциями
Представим, что вам очень захотелось вернуть свой сайт к состоянию, в котором он был неделю назад. В жизни часто происходит подобное: например, неделю назад ошибки не было, а теперь есть и хочется посмотреть что было раньше. Или вы хотели использовать библиотеки, которые добавляют новые поля, а потом передумали и решили хранить всё в простом CharField
.
Вернуться к старому коду очень легко, если вы используете репозиторий git. Но за время разработки модели данных тоже менялись и их также следует откатить назад вместе с кодом.
Неделю назад вы были на миграции 0005
. Сейчас showmigrations
показывает список из 8 миграций:
appname
[X] 0001_initial
[X] 0002_new_model
[X] 0003_auto_20190805_1906
[X] 0004_new_field
[X] 0005_auto_20190805_1920
[X] 0006_auto_20190807_1545
[X] 0007_auto_20190808_1301
[X] 0008_auto_20190808_1314
Получается, нужно отменить 3 последние миграции. Делается это одной командой:
$ python manage.py migrate appname 0005
Django самостоятельно удалит таблицы и столбцы в БД, которые появились в последних 3 миграциях. Если в последних миграциях таблицы удалялись, то они вернутся назад, хотя и останутся пустыми — Django может вернуть таблицы, но не может вернуть их содержимое. То же самое работает и наоборот: таблицы, которые удаляются при откатывания миграции, удаляются вместе с данными.
showmigrations
теперь выдаст 3 последние миграции без крестиков:
appname
[X] 0001_initial
[X] 0002_new_model
[X] 0003_auto_20190805_1906
[X] 0004_new_field
[X] 0005_auto_20190805_1920
[ ] 0006_auto_20190807_1545
[ ] 0007_auto_20190808_1301
[ ] 0008_auto_20190808_1314
Выполнить не все миграции
Этот же инструмент позволяет запускать миграции частями, а не только все разом. Допустим, вы сейчас на пятой миграции:
[X] 0004_new_field
[X] 0005_auto_20190805_1920
[ ] 0006_auto_20190807_1545
[ ] 0007_auto_20190808_1301
[ ] 0008_auto_20190808_1314
Теперь попробуем переместиться на седьмую миграцию:
$ python manage.py migrate appname 0007
Вместе с ней исполнилась и шестая миграция. Это связано с тем, что миграции расположены в “цепочке” и строго следуют друг за другом. Седьмая запускается только тогда, когда исполнены все миграции до неё:
[X] 0004_new_field
[X] 0005_auto_20190805_1920
[X] 0006_auto_20190807_1545
[X] 0007_auto_20190808_1301
[ ] 0008_auto_20190808_1314
Попробуйте бесплатные уроки по Python
Получите крутое код-ревью от практикующих программистов с разбором ошибок и рекомендациями, на что обратить внимание — бесплатно.
Переходите на страницу учебных модулей «Девмана» и выбирайте тему.