Миграции Django: SeparateDatabaseAndState против --fake

Допустим, у меня есть модель:

class MyModel(models.Model):
  ...
  field_no_need_anymore = Charfield(...)

Я хочу удалить поле field_no_need_anymore, но не хочу сразу применять изменения к базе данных - я уберу этот столбец вручную позже (на следующий день или через день). В Django для этого случая у меня есть два варианта:

python manage.py migrate --fake

или добавьте это в миграцию:

operations = [
  migrations.SeparateDatabaseAndState(
    state_operations=[
      migrations.RemoveField(
        model_name='mymodel',
        name='field_no_need_anymore',
      )
    ],
    database_operations=[]
  )
]

В обоих случаях в таблице django_migrations появится новая запись, а изменения в целевой таблице не будут применены. Итак, когда вы используете --fake и когда SeparateDatabaseAndState?

Ну, ответов нет... Попробую объяснить, что я нашел.

Флаг - подделка

Лучше использовать для приведения состояния Django в соответствие с реальным состоянием базы данных. Например, таблица базы данных содержит столбцы «col1» и «col2», но модель Django содержит только поля «col1», «col2» и «col3». Мы удаляем поле «col3» и запускаем миграцию с флагом --fake. Теперь рассмотрим следующий пример: у нас есть поля «col1» и «col2» в таблице базы данных и в модели Django. Мы удаляем поле «col1» из модели, запускаем миграцию с флагом --fake, ожидая, что впоследствии столбец будет удален. Но затем мы решаем откатить миграцию до того, как опустим колонку. Это не удастся, потому что Django попытается восстановить удаленный «col2», пока он существует в таблице базы данных.

SeparateDatabaseAndState

Этот вариант более безопасен - нет проблем с откатом, так как эта миграция не работает с базой данных (кроме таблицы django_migration). Его можно использовать в случае, когда мы хотим отложить изменения в базе данных. В нашей компании мы выбрали этот вариант для удаления неиспользуемого поля из Django-модели (мы не можем сразу применить изменения к базе данных из-за запущенных процессов, которые используют старое состояние Django-моделей). На втором шаге мы делаем еще одну миграцию - без SeparateDatabaseAndState (по сути, то же самое - с удалением поля внутри), которая будет применена к базе данных и отбросит колонку.

SeparateDatabaseAndState позволяет смешивать и сопоставлять аспекты операций, связанные с базой данных и состоянием. Он принимает два списка операций. Если требуется применить состояние, используется список state_operations. При запросе на применение изменений в базе данных будет использоваться список database_operations. Вы можете использовать это, если хотите отделить состояние миграций от фактического состояния базы данных. Делайте это только в том случае, если вы действительно знаете, что делаете, потому что если фактическое состояние базы данных и представление Django о состоянии не синхронизируются, это может нарушить работу фреймворка миграции и привести к потере данных. Пожалуйста, будьте осторожны и тщательно проверяйте свои операции с базой данных и состоянием.

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

Вернуться на верх