Каков рекомендуемый подход к сбросу истории миграции с использованием Django South? - PullRequest
154 голосов
/ 07 января 2011

Я накопил довольно много миграций, используя South (0.7) и Django (1.1.2), которые начинают занимать довольно много времени в моих модульных тестах. Я хотел бы сбросить базовый уровень и начать новый набор миграций. Я просмотрел документацию South , выполнил обычный поиск в Google / Stackoverflow (например, "История миграции django south (сбросить, удалить или удалить)") и не нашел ничего очевидного.

Один из подходов, который я обдумывал, включал бы «начало заново» путем «удаления» на юг или «очистку» истории вручную (например, очистка таблицы БД, удаление файлов миграции из директора миграции) и просто повторный запуск,

. / Manage.py schemamigration southtut --initial

Так что, если кто-то делал это раньше и имел несколько советов / предложений, они были бы очень благодарны.

Ответы [ 7 ]

188 голосов
/ 24 января 2013

Если вам нужно выборочно (только для одного приложения) сбросить миграцию, которая занимает слишком много времени, это сработало для меня.

rm <app-dir>/migrations/*
python manage.py schemamigration <app-name> --initial
python manage.py migrate <app-name> 0001 --fake  --delete-ghost-migrations

Не забудьте вручную восстановить все зависимости в других приложениях, добавив строки типа depends_on = (("<other_app_name>", "0001_initial"),("<yet_another_app_name>", "0001_initial")) в ваш файл <app-dir>/migrations/0001_initial.py, как первый атрибут в вашем классе миграции чуть ниже class Migration(SchemaMigration):.

Затем вы можете ./manage.py migrate <app-name> --fake --delete-ghost-migrations в других средах, за этот SO-ответ . Конечно, если вы имитируете удаление или подделку migrate zero, вам нужно будет вручную удалить все оставшиеся таблицы БД с миграцией, подобной this .

Более ядерный вариант - ./manage.py migrate --fake --delete-ghost-migrations на сервере реального развертывания, за которым следует [my] sqldump. Затем направьте этот дамп в [my] sql в тех средах, где вам нужна перенастроенная, полностью заполненная база данных. Южная кощунство, я знаю, но работало на меня.

122 голосов
/ 11 января 2011

РЕДАКТИРОВАТЬ - я помещаю комментарий внизу вверху, так как важно прочитать его до> принятого ответа, следующего за @ andybak

@ Доминик: Ваш совет по поводу настройки manage.py на юг опасен и может уничтожить базу данных, если есть сторонние приложения, использующие юг в проекте, как указано @thnee ниже. Так как ваш Ответ имеет так много голосов, я бы очень признателен, если бы вы могли редактировать это и добавить хотя бы предупреждение об этом, или (еще лучше) изменить его отражать подход @hobs (который так же удобен, но не влияет на другие приложения) - спасибо! - Крив Мар 26 '13 в 9: 09

Принятый ответ следует ниже:

Во-первых, ответ южного автора :

Если вы позаботитесь о том, чтобы сделать это во всех развертываниях одновременно, с этим не должно быть никаких проблем. Лично я бы сделал:

    rm -r appname/migrations/ 
    ./manage.py reset south 
    ./manage.py convert_to_south appname 

(Обратите внимание, что часть «reset south» очищает записи миграции для ВСЕХ приложений, поэтому убедитесь, что вы либо запустите две другие строки для всех приложений, либо удалите выборочно).

Вызов convert_to_south в конце делает новую миграцию и подделывает ее (поскольку ваша база данных уже имеет соответствующие таблицы). Во время процесса не нужно удалять все таблицы приложений.

Вот что я делаю на своем рабочем сервере dev +, когда мне нужно избавиться от всех этих ненужных миграций разработчиков:

  1. Убедитесь, что у нас одинаковая схема БД с обеих сторон
  2. удалить каждую папку миграции с обеих сторон
  3. run ./manage.py сбросить юг (как говорится в посте) с обеих сторон = очищает южную таблицу *
  4. run ./manage.py convert_to_south с обеих сторон (фиктивная миграция 0001)
  5. тогда я могу перезапустить, чтобы выполнить миграции и отправить папки миграций на моем сервере

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

54 голосов
/ 10 марта 2013

Благодаря ответам Доминика Гвардиолы и Хобса, это помогло мне решить сложную проблему.Однако есть несколько проблем с решением, вот мое решение.

Использование manage.py reset south - - не очень хорошая идея , если у вас есть сторонние приложения , который использует Юг, например django-cms (в основном все использует Юг).

reset south удалит всю историю миграции для всех установленных вами приложений.

Теперь учтите, что выобновите до последней версии django-cms, она будет содержать новые миграции, такие как 0009_do_something.py.Юг наверняка будет сбит с толку, когда вы попытаетесь запустить эту миграцию, не имея 0001 - 0008 в истории миграции.

Гораздо лучше / безопаснее выборочно сбрасывать только те приложения, которые у вас естьподдержание .


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

1.Удалить историю миграции для моих приложений

sql> delete from south_migrationhistory where app_name = 'my_app';

2.Удалить миграции для моих приложений

$ rm -rf my_app/migrations/

3.Создать новые начальные миграции для моих приложений

$ ./manage.py schemamigration --initial my_app

4.Поддельное выполнение начальных миграций для моих приложений

Это вставляет миграции в south_migrationhistory, не затрагивая реальные таблицы:

$ ./manage.py migrate --fake my_app

Шаг 3 и 4 на самом деле является просто более длинным вариантом manage.py convert_to_south my_app, но я предпочитаю этот дополнительный контроль в такой деликатной ситуации, как изменение производственной базы данных.

7 голосов
/ 30 июля 2013

Как и в случае с тобой (см. Ее ответ), мы используем более мягкий подход к предложению автора на юге (Эндрю Годвин), приведенному в другом месте здесь, и мы отделяем то, что мы делаем с базой кода, от того, что мы делаем с базой данных во время развертывания, потому что нам нужно, чтобы развертывания были повторяемыми:

Что мы делаем в коде:

# Remove all the migrations from the app
$ rm -fR appname/migrations
# Make the first migration (don't touch the database)
$ ./manage.py schemamigration appname --initial

Что мы делаем с базой данных после развертывания этого кода

# Fake the migration history, wiping out the rest
$ ./manage.py migrate appname --fake --delete-ghost-migrations
1 голос
/ 27 сентября 2012

Если вы просто работаете на машине разработчика, я написал команду управления, которая в значительной степени выполняет то, что предложил Доминик.

http://balzerg.blogspot.co.il/2012/09/django-app-reset-with-south.html

В отличие от предложения автора на юге, это НЕ ВРЕДИТ другим установленным приложениям, использующим юг.

0 голосов
/ 17 ноября 2014

удалить необходимый файл из папки приложения

путь к экземпляру

 cd /usr/local/lib/python2.7/dist-packages/wiki/south_migrations

wiki - это мое приложение

0 голосов
/ 21 мая 2013

Следующие только если вы хотите сбросить все приложения.Пожалуйста, сделайте резервную копию всех ваших баз данных до этой работы.Также запишите свои зависимость_ на в исходных файлах, если они есть.

На этот раз:

(1) find . -type d -name migrations -exec git rm -rf '{}' \;
(2) find . -type d -name migrations -exec rm -rf '{}' \;
(3) ./manage.py schemamigration <APP_NAME> --initial
(4) [GIT COMMIT]

Проверьте загрузку проекта перед отправкой.Затем для каждого локального / удаленного компьютера примените следующее:

(5) [GIT PULL]
(6) ./manage.py reset south
(7) ./manage.py migrate --fake

Выполните начальную (3) для каждого приложения , которое вы хотите повторно задействовать.Обратите внимание, что reset (6) удалит только историю миграции, поэтому не будет вреден для библиотек.Ложные миграции (7) вернут историю миграции любых установленных сторонних приложений.

...