re-order migrations to match restructured project

Could someone offer me a tip as to how to go about re-ordering my migration files to match my newly restructured project? There is only one migration in the admin app so it seems that it is not an unreasonable goal.

As was discussed in my post the-drawbacks-of-using-an-apps-sub-directory I started a project with my applications (only one) were grouped in an ‘apps’ directory at the same level of the project:

└── myproject                                                <- project root
    ├── myadmin                                             <- Django root
    │     ├── migrations                                    <- project migrations
    │     │     ├── 0001_initial.py
    │     │     └── __init__.py
    │     ├── apps                                             <- Home for all Django Apps
    │     │     ├── appcustom                            <- appcustom app
    │     │     │     ├── migrations                      <- dir for appcustom app migrations
    │     │     │     │     ├── 0001_initial.py
    │     │     │     │     ├── 0002_alter_asset_asset_type_code_and_more.py
    │     │     │     │     ├── 0003_alter_another_entity_and_more.py
    │     │     │     │     └── __init__.py

I decided to see if I could revert the project to a structure that is more in line with convention (@KenWhitesell feel free to say ‘I warned you’). So I refactored my app by changing all the references to the following:

└── myproject                                                <- project root
    ├── appcustom                                          <- appcustom app
    │     ├── migrations                                   <- dir for appcustom app migrations
    │     ├── 0001_initial.py
    │     ├── 0002_alter_asset_asset_type_code_and_more.py
    │     ├── 0003_alter_another_entity_and_more.py
    │     └── __init__.py
    ├── myadmin                                             <- Django root 
    │     ├── migrations                                    <- project migrations
    │     │     ├── 0001_initial.py
    │     │     └── __init__.py

Miraculously everything worked after pointing my app back at the database and life was good. Or so it seemed until I lost my local database running in a local container when I forgot to point the storage to something outside of the container and I needed to run migrations. However, I have just realized that Django no longer knows which migration to apply first. When I go to migrate my restored database I get the following error:

django.db.migrations.exceptions.InconsistentMigrationHistory: Migration admin.0001_initial is applied before its dependency appcustom.0001_initial on database 'default'.

I learned that I can create a migration “plan” by doing
python migrate.py showmigrations -p
that seems like it might be promising. I could then compare the plan for the old project and for the new project and try and re-order the migrations.

If you only have this one instance of your project running, or if all the instances are under your control (and not too numerous), and they are all up-to-date regarding the database schema, you could delete all the migration files, empty the migration table in the database(s), rerun makemigrations and migrate --fake.

All those factors being the case for me, that might be the best option. I’ll take a look at this and respond if it works.

@KenWhitesell the approach you suggested looked like it has worked. Although it took a few times - probably due to my misinterpretation of your steps or not understanding the assumptions of how makemigrations should be run.

First attempt:

  • deleted all files from the migrations folders within my project
  • deleted all of the records (actually truncated) from the django_migrations table
  • ran python manage.py makemigrations
  • ran python manage.py migrate --fake

The django_migrations table was re-populated and I was informed in the console that a number of migrations were applied. However, I did not see any migration files in my admin nor application migrations folders; I thought that makemigrations would re-create the scripts based on the existing data structure. After reading a couple more StackOverflow suggestions I tried again.

Second attempt.

  • removed the migrations folders (now empty)
  • dropped the migrations table entirely (it had been repopulated)
  • ran python manage.py makemigrations myproject and python manage.py makemigrations myapp and this time the migrations were (re) created in the migrations folders
  • ran python manage.py migrate --fake and the command ran as before.

I suspect that it was the targetted makemigrations commands that ultimately yielded the results rather than the deletion of the migrations folders and dropping of the django_migrations table. Does this ring true to your experience?

I’ll mark your response as a solution, Ken. Thank you for your help.

You probably deleted the __init__.py file from the migrations directories - that caused makemigrations to not “see” that directory as a module.

You should have only deleted the migration files.

It would, if the migrations directory has the __init__.py file in it.

The “targeted” makemigrations forces the creation of an __init__.py file inside the migrations directory when required.