Reputation: 63
Let's say I have a model:
class MyModel(models.Model):
...
field_no_need_anymore = Charfield(...)
I want to remove field_no_need_anymore, but I don't want to apply changes to the database immediately - I will drop this column manually later (next day or day after). In Django for this case I have two options:
python manage.py migrate --fake
or add this to the migration:
operations = [
migrations.SeparateDatabaseAndState(
state_operations=[
migrations.RemoveField(
model_name='mymodel',
name='field_no_need_anymore',
)
],
database_operations=[]
)
]
In both cases there will be a new record in django_migrations table, while no changes to the target table will be applied. So, when you use --fake and when SeparateDatabaseAndState?
Upvotes: 0
Views: 97
Reputation: 4096
SeparateDatabaseAndState allows you mix and match the database and state aspects of operations. It accepts two lists of operations. When asked to apply state, it will use the state_operations list. When asked to apply changes to the database, it will use the database_operations list. You can use this if you want to detach the state of your migrations from the actual state of your database. Only do this if you really know what you are doing because if the actual state of the database and Django’s view of the state get out of sync, it can break the migration framework, and lead to data loss. Please exercise caution and check your database and state operations carefully.
--fake is used to mark migrations as applied without actually running the SQL to change your database schema. You can use it to manipulate the current migration state directly if you’re manually applying changes; It should also be noted that using --fake
runs the risk of putting the migration state table into a state where manual recovery will be needed to make migrations run correctly.
Upvotes: 0
Reputation: 63
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.
Upvotes: 0