У меня есть приложение django с четырьмя моделями. Теперь я понимаю, что одна из этих моделей должна быть в отдельном приложении. У меня действительно установлен юг для миграций, но я не думаю, что он может справиться с этим автоматически. Как перенести одну из моделей из старого приложения в новое?
Также имейте в виду, что мне нужно, чтобы это был повторяемый процесс, чтобы я мог перенести производственную систему и тому подобное.
django
migration
django-south
Apreche
источник
источник
Ответы:
Как мигрировать, используя юг.
Допустим, у нас есть два приложения: общее и конкретное:
Теперь мы хотим переместить модель common.models.cat в конкретное приложение (а именно в specific.models.cat). Сначала внесите изменения в исходный код, а затем запустите:
Теперь нам нужно отредактировать оба файла миграции:
Теперь оба миграции приложений знают об изменениях, и жизнь - отстой чуть меньше :-) Установка этой взаимосвязи между миграциями - ключ к успеху. Теперь, если вы это сделаете:
выполнит как миграцию, так и
перенесет вещи вниз.
Обратите внимание, что для обновления схемы я использовал обычное приложение, а для перехода на более раннюю версию я использовал конкретное приложение. Это потому, что здесь работает зависимость.
источник
orm['contenttypes.contenttype'].objects.filter
в обратной части0003_create_cat
тоже не должно быть линии ? Также хочу поделиться советом. Если у вас есть индексы, их тоже нужно будет изменить. В моем случае это были уникальные индексы, поэтому мой прогноз выглядит так:db.delete_unique('common_cat', ['col1'])
db.rename_table('common_cat', 'specific_cat')
db.delete_unique('specific_cat', ['col1'])
orm['contenttypes.contenttype']
, вам также необходимо добавить--freeze contenttypes
параметр в своиschemamigration
команды.python manage.py schemamigration specific create_cat --auto --freeze common
чтобы получить доступ к модели кошки из общего приложения.Для того, чтобы построить на Potr Czachur «s ответ , ситуации, связанные с ForeignKeys более сложными и должны быть обработаны немного по- другому.
(Следующий пример основывается на
common
иspecific
программы упомянутого к в текущем ответ).затем изменится на
Бег
будет генерировать следующие миграции (я намеренно игнорирую изменения Django ContentType - см. ранее упомянутый ответ, чтобы узнать, как с этим справиться):
Как видите, FK необходимо изменить, чтобы он ссылался на новую таблицу. Нам нужно добавить зависимость, чтобы мы знали порядок, в котором будут применяться миграции (и, таким образом, таблица будет существовать до того, как мы попытаемся добавить к ней FK), но мы также должны убедиться, что откат назад тоже работает, потому что зависимость применяется в обратном направлении .
Согласно документации Южной ,
depends_on
будет гарантировать , что0004_auto__add_cat
бежит перед0009_auto__del_cat
при переходе вперед , но в порядке , обратном порядку при переходе в обратном направлении . Если мы оставилиdb.rename_table('specific_cat', 'common_cat')
вspecific
откате, тоcommon
откат потерпит неудачу при попытке перенести ForeignKey , так как таблица ссылочной таблица не существует.Надеюсь, это ближе к «реальной ситуации», чем существующие решения, и кто-то сочтет это полезным. Ура!
источник
Модели не очень тесно связаны с приложениями, поэтому перемещать их довольно просто. Django использует имя приложения в имени таблицы базы данных, поэтому, если вы хотите переместить свое приложение, вы можете либо переименовать таблицу базы данных с помощью оператора SQL
ALTER TABLE
, либо, что еще проще, просто использоватьdb_table
параметр вMeta
классе вашей модели для ссылки на старое имя.Если вы до сих пор использовали ContentTypes или общие отношения где-либо в вашем коде, вы, вероятно, захотите переименовать
app_label
тип контента, указывающий на движущуюся модель, чтобы существующие отношения были сохранены.Конечно, если у вас вообще нет данных, которые нужно сохранить, проще всего полностью удалить таблицы базы данных и запустить их
./manage.py syncdb
снова.источник
Вот еще одно исправление отличного решения Потра. Добавьте следующее к конкретному / 0003_create_cat
Если эта зависимость не установлена Юг не будет гарантировать , что
common_cat
таблица существует в то время , когда конкретный / 0003_create_cat запускается, бросаяdjango.db.utils.OperationalError: no such table: common_cat
ошибку на вас.South выполняет миграции в лексикографическом порядке, если явно не задана зависимость. Поскольку это
common
происходит до того, какspecific
всеcommon
миграции будут выполняться перед переименованием таблицы, вероятно, он не будет воспроизводиться в исходном примере, показанном Потром. Но если переименоватьcommon
вapp2
иspecific
кapp1
вам будет столкнуться с этой проблемой.источник
Процесс, на котором я остановился, так как я был здесь несколько раз и решил формализовать его.
Это был первоначально построен на ответ Potr Czachur в и ответ Мэтт Бриансона в , используя Южный 0.8.4
Шаг 1. Обнаружение дочерних внешних ключей
Итак, в этом расширенном случае мы обнаружили другую связанную модель, например:
Шаг 2. Создайте миграции
Шаг 3. Контроль версий: зафиксируйте изменения.
Делает процесс более повторяемым, если вы сталкиваетесь с конфликтами слияния, например, когда товарищи по команде пишут миграции в обновленных приложениях.
Шаг 4. Добавьте зависимости между миграциями.
В основном
create_kittycat
зависит от текущего состояния всего, а потом все зависит отcreate_kittycat
.Шаг 5. Изменение переименования таблицы, которое мы хотим внести.
Шаг 6. Только если вам нужно backwards () для работы И получить KeyError, работающую в обратном направлении.
Шаг 7. Протестируйте - того, что мне подходит, может не хватить для вашей реальной жизненной ситуации :)
источник
Таким образом, использование исходного ответа от @Potr выше не сработало для меня на South 0.8.1 и Django 1.5.1. Я публикую ниже то, что сработало для меня, в надежде, что это поможет другим.
источник
Я собираюсь дать более точную версию одной из вещей, предложенных Дэниелом Розманом в своем ответе ...
Если вы просто измените
db_table
атрибут Meta модели, которую вы переместили, чтобы он указывал на существующее имя таблицы (вместо нового имени, которое Django даст ему, если вы удалите и сделали asyncdb
), вы можете избежать сложных миграций на юг. например:Оригинал:
После переезда:
Теперь вам просто нужно выполнить миграцию данных, чтобы обновить
app_label
forMyModel
вdjango_content_type
таблице, и все должно быть в порядке ...Запустите,
./manage.py datamigration django update_content_type
затем отредактируйте файл, который South создает для вас:источник