Search code examples
djangodjango-migrations

Django Migrations stuck after executing in incorrect order


I made two changes to different models in my database.
The first

operations = [
        migrations.DeleteModel(
            name='Settlement',
        ),
    ]

And the second:

operations = [
        migrations.RemoveField(
            model_name='invoice',
            name='settlement_deducted',
        ),
        migrations.RemoveField(
            model_name='invoice',
            name='settlement_supporting',
        ),
]

The issue is that they ran in this order, and the second one failed. The field being removed in the second migration uses the "Settlement" model, but since that model was deleted in the first migration it throws this error:

ValueError: The field invoices.Invoice.settlement_deducted was declared with a lazy reference to 'accounting.settlement', but app 'accounting' doesn't provide model 'settlement'.
The field invoices.Invoice.settlement_supporting was declared with a lazy reference to 'accounting.settlement', but app 'accounting' doesn't provide model 'settlement'

Now when I try to do anything to fix it, it seems to just be stuck in that error state and continuously throws that same error.
I have tried reverting the first migration to the previous migration on that model, adding that model back in and running makemigrations and then migrate so that the Settlement model exists again, and deleting the second migration (though it was never run anyway). All of these options are still throwing the same error.

I am surprised that Django didn't catch this dependency issue for me, but it is unfortunately too late for that now. I also tried adding it as a dependency, but then it just threw the error saying that a migration has been migrated before one of its dependencies.


Solution

  • I was successfully able to solve the issue! These are the steps I took:

    1. add the second migration as a dependency to the first one
    2. go to the django_migrations table in the db and delete the first migration (which ran already)
    3. run ONLY the second migration
    4. fake the first migration (since it already ran)
    5. (unnecessary step but necessary in my case) run migrate normally to finish migrating uninvolved migrations from other apps