If you need to migrate Django model, and it happens to be an AUTH_USER_MODEL
Hope you never need this. Here are clues I can manage to write down before I forgot any steps. The steps are not verified because I don’t want to do it again.
If the model you are migrating is not an AUTH_USER_MODEL, follow this.
I would copy those steps here and modify them to migrate AUTH_USER_MODEL.
Assume we have these migration files in the beginning: 0001_initial_in_app1.py
, 0001_initial_in_app2.py
- Copy the AUTH_USER_MODEL from
app1
toapp2
, setdb_table
, and DO NOT change any foreign key references. - Run
makemigrations
. Assume the generated migration files are named0002_migration_app1.py
and0002_migrration_app2.py
. Wrap both migration files instate_operations
like the following:
In 0002_migration_app1.py
operations = [
...
migrations.DeleteModel(
name='YourModel',
),
...
]
becomes
operations = [
migrations.SeparateDatabaseAndState(state_operations=[
...
migrations.DeleteModel(
name='YourModel',
),
...
])
]
3. Add a dependency, ('app1', '0002_migration_app1')
, in the 0002_migration_app2.py
4. Point all of the foreign key references to the new model.
If you aren’t using string references, give the imported model an alias (DO NOT remove it) so it does not compete with the imported class.
5. Run makemigrations
to let the foreign changes actually happen. Assume the generated file is called 0003_change_fk_app2.py
.
6. Add ('app2', '0002_migration_app2')
as a dependency in 0003_change_fk_app2.py
.
7. Temporarily remove the models from app1
.
8. Make AUTH_USER_MODEL points to app2.YOUR_MODEL
.
If any past model has ever point to AUTH_USER_MODEL, it would point to new model now. If Django complains about conflict column names in step 10, make them as None, run makemigrations
, adjust 0002_migration_app2.py
accordingly, and try it out.
9. Move initial = True
from 0001_initial_in_app2.py
to 0002_migration_app2.py
and make dependency in 0001_initial_in_app2.py
as ('app2', '0002_migration_app2')
only. And add ('auth', '__first__')
as an extra dependency in 0002_migration_app2.py
10. Run makemigrations
. Assume this generate file 0003_delete_model_app1.py
. And wrap 0003_delete_model_app1.py
in state_operations
. Add ('app2', '0003_change_fk_app2')
as a dependency in 0003_delete_model_app1.py
. If Django is fine about the change, and revoke the changes in step 8.
11. Run python manage.py dbshell
and execute DELETE FROM django_migrations WHERE app IN ("app1", "app2", "account", "admin", "authtoken", "socialaccount", auth");
12. Run the following commands:
python manage.py migrate --fake app1 0001
python manage.py migrate app2 0002
python manage.py migrate --fake account
python manage.py migrate --fake admin
python manage.py migrate --fake authtoken
python manage.py migrate --fake socialaccount
python manage.py migrate --fake auth
python manage.py migrate --fake main
python manage.py migrate app1
python manage.py migrate app2
13. Copy 0001_initial_in_app1.py
to 0002_migration_app2.py
and remove 0003_change_fk_app2.py
in app2
.
14. You may delete app1
.
(Optional) Remove db_table
in app2.YOUR_MODEL
and run makemigrations
(This would give you 0003_change_table_name_app2.py
), migrate
again to apply new table name.