Миграции 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?
Well, no answers... Will try to explain, what I found.
Flag --fake
Better to use to align Django state to the real database state. For example, database table contains columns "col1" and "col2", but Django model contains only fields "col1", "col2" and "col3". We remove field "col3" and run migration with flag --fake. Now consider this example: we have "col1" and "col2" in database table and in Django model. We remove field "col1" from model, run migration with --fake, expecting to drop the column later. But then we decide to roll back migration before dropping the column. This will fail, because Django will try to restore removed "col2", while it exists in the database table.
SeparateDatabaseAndState
This option is more secure - no issues with roll back, because this migration doesn't work with database (except table django_migration). It may be used to the case, when we want to postpone database changes. In our company we chose this option to remove unused field from Django model (we can't apply changes to the database immediately, because of running processes, that use the old state of Django models). On the second step we make another migration - without SeparateDatabaseAndState (basically the same - with field removal inside), that will be applied to the database and will drop the column.