Search code examples
pythondjangodjango-migrationsmakemigrations

Changes detected after squashmigrations


python manage.py showmigrations shows:

mainapp
 [X] 0001_initial
...
 [X] 0240_employer_data
 [X] 0241_person_metadata
 [X] 0242_personemployer_employerworkplace
 [X] 0243_personemployer_employed_personemployer_stage
 [X] 0244_remove_employerworkplace_and_more

I ran:

python manage.py squashmigrations mainapp 0244

and now showmigrations shows:

mainapp
 [-] 0001_squashed_0244_remove_employerworkplace_and_more (244 squashed migrations) Run 'manage.py migrate' to finish recording.

But python manage.py migrate reports the errors:

No migrations to apply.
Your models in app(s): 'mainapp' have changes that are not yet reflected in a migration, and so won't be applied.
Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them.

How can there be changes detected immediately after running squashmigrations without doing anything in between?

python manage.py makemigrations --dry-run shows many "Alter field" lines like

Migrations for 'mainapp':
  mainapp/migrations/0001_squashed_0244_remove_employerworkplace_and_more.py
    ~ Alter field field on employergroup
    ~ Alter field image_alt on employee
    ~ Alter field context on employer
    ...

I would expect that after I run squashmigrations, makemigrations would show "No changes detected"

So what happened? What might have caused this bizarre situation? How might I fix it?


Solution

  • You can "manually" squash migrations, by

    1. clear migration history

      python manage.py migrate --fake myapp zero
      
    2. Remove the migration files

      rm django/myapp/migrations/*.py
      
    3. Make new migration files (there will only be one, this will make the new initial migration file)

      python manage.py makemigrations
      
    4. And migrate to it

      python manage.py migrate --fake-initial
      

    The reason for --fake and --fake-initial are to prevent the database from being updated during this process.