Django migrate --fake и --fake -инициал объяснил

Я пользуюсь Django около 2 лет, и есть функция, которой я всегда боялся: фальсификация миграций.

Я посмотрел почти везде, и большую часть информации я могу получить из документации, где говорится, что:

--fake

Сообщает Django пометить миграции как примененные или не примененные, но без фактического запуска SQL для изменения схемы базы данных.

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

--fake -initial

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

Я получил общее представление и почему кто-то хотел бы использовать эту функцию. Но я не понимаю ту часть, где говорится, что это предназначено только для опытных пользователей.

Может кто-нибудь объяснить, что происходит за кулисами и почему потребуется ручное восстановление.

НОТА

Я не ищу точные необработанные запросы SQL, которые выполняются при имитации миграции. Я только ищу общее представление о том, что происходит за makemigrations и, возможно, пример того, почему фальсификация миграции может привести к makemigrations что рабочие makemigrations будут работать некорректно.

Ответ 1

Это связано с проблемой базы данных, похожей на конфликт слияния в исходном коде (git), если вам нужно объединить две ветки с похожими моделями или переключаться между ними. Никому не нравится это намеренно.

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

./manage sqlmigrate some_app 0007_new_migration >customized-some_app-0007_new_migration.sql

сравните содержимое с изменениями, внесенными на прошлой неделе, и удалите или закомментируйте команду, которая все еще применяется и не может быть повторена. Запустите все остальные SQL вручную. Отметьте, что миграция будет применена автоматически:

./manage migrate --fake some_app 0007_new_migration

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

ОБНОВЛЕНИЕ: Таблица миграции django_migrations представляет собой простой список миграций, применяемых во всех приложениях. Строки в этой таблице всегда должны быть синхронизированы со структурой базы данных. Миграции могут быть применены обычным migrate. (или не применяется обратной миграцией в старое состояние, обычно с некоторой потерей данных, конечно). Ложная миграция применяет изменение только к таблице django_migrations.

me => select * from django_migrations;
 id | app      |          name           |            applied            
----+----------+-------------------------+-------------------------------
  1 | some_app | 0001_initial            | 2017-10-16 06:11:07.31249+02
  2 | some_app | 0002_auto_20171016_1905 | 2017-10-17 02:05:48.979295+02

Миграция (файл) - это описание инкрементных изменений, а также информация, позволяющая оценить разницу между models.py с момента последней миграции, которая сравнивается при выполнении makemigrations. Этого также достаточно для случая, когда некоторые таблицы изначально не управлялись, и ими можно было управлять позже. (поэтому неуправляемые таблицы также записываются.)

ОБНОВЛЕНИЕ: Пример: как sqlmigrate с --fake можно использовать для исправления поврежденной базы данных путем миграции (для воссоздания удаленной таблицы).