How to Solve: django.db.migrations.exceptions.InconsistentMigrationHistory When Running migrate

In this article, I walk through how to solve the InconsistentMigrationHistory error when running a migration. While wiping your database is a solution, it isn’t ideal, especially if you’re working in a non-dev environment. Here’s how to do it safely.

The Error

This error occurs sometimes if you’re running a migration:

$ ./manage.py migrate
Traceback (most recent call last):
File "<my_project>/./manage.py", line 22, in <module>
main()
File "<my_project>/./manage.py", line 18, in main
execute_from_command_line(sys.argv)
File "<my_project>/.venv/lib/python3.10/site-packages/django/core/management/__init__.py", line 442, in execute_from_command_line
utility.execute()
File "<my_project>/.venv/lib/python3.10/site-packages/django/core/management/__init__.py", line 436, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "<my_project>/.venv/lib/python3.10/site-packages/django/core/management/base.py", line 412, in run_from_argv
self.execute(*args, **cmd_options)
File "<my_project>/.venv/lib/python3.10/site-packages/django/core/management/base.py", line 458, in execute
output = self.handle(*args, **options)
File "<my_project>/.venv/lib/python3.10/site-packages/django/core/management/base.py", line 106, in wrapper
res = handle_func(*args, **kwargs)
File "<my_project>/.venv/lib/python3.10/site-packages/django/core/management/commands/makemigrations.py", line 156, in handle
loader.check_consistent_history(connection)
File "<my_project>/.venv/lib/python3.10/site-packages/django/db/migrations/loader.py", line 327, in check_consistent_history
raise InconsistentMigrationHistory(
django.db.migrations.exceptions.InconsistentMigrationHistory: Migration socialaccount.0001_initial is applied before its dependency sites.0001_initial on database 'default'.

In this case, this is because I had installed and migrated the socialaccount app before I added django.contrib.sites to INSTALLED_APPS .

I had already deployed this to production, so I didn’t want to do a database wipe.

Instead, I used this procedure to get the project back on track.

Enter the dbshell

Enter the DB shell. My database is PostgreSQL. If you’re using something different, ensure the queries are converted accordingly.

$ ENV_FILE=../.env.staging ./manage.py dbshell

First back up the migrations table.

CREATE TABLE bak1_django_migrations AS SELECT * FROM django_migrations;

Let’s get a bearing on what migrations are already applied.

> SELECT DISTINCT(app) FROM django_migrations WHERE app IN ('socialaccount', 'sites');
app
-------------------
socialaccount

Yup, as expected, looks like socialaccount was applied, but not sites .

Now we’re going to delete the socialccount migration. Remember how we made a back-up previously? If not, do that first. It’s just a single copy-and-paste command. Just do it.

So, on to the deletion:

DELETE FROM django_migrations WHERE app = 'socialaccount';

Also delete the tables. If your tables have data, then back them up. In this case (because socialaccount has relational tables), I needed to delete several:

DROP TABLE socialaccount_socialapp;
DROP TABLE socialaccount_socialaccount CASCADE;

If your tables had data, don’t worry (I mean, worry if you DIDN’T back up your tables). We’ll restore the data in a bit.

Our Migration Should Succeed Now

Now our migration should succeed:

$ ENV_FILE=../.env.staging ./manage.py migrate
using ENV_PATH <env_path>
System check identified some issues:

Operations to perform:
Apply all migrations: ....
Running migrations:
Applying sites.0001_initial... OK
Applying sites.0002_alter_domain_unique... OK
Applying socialaccount.0001_initial... OK
Applying socialaccount.0002_token_max_lengths... OK
Applying socialaccount.0003_extra_data_default_dict... OK
...

If the tables you deleted (e.g. the socialaccount tables) had data in them, then restore them from the backup tables:

INSERT INTO socialaccount_socialaccount
SELECT * FROM bak1_socialaccount_socialaccount;

This assumes these tables are not part of a new migration (e.g. they have the exact same schema). If there’s any migration applied, then it will require more work. Probably fodder for another article.

📢 Comment below: Have you encountered this error? What was your solution?

👉‍‍ Share this article with 3 of your friends or colleagues. On Twitter, LinkedIn or Mastodon. Be sure to tag me in the post. Helps me know if my content is still relevant.

💓 Subscribe to DamnGoodTech on Ko-Fi for as little as $7/mo. Get articles 3 days early and get a shout-out on each article! That’s like hiring a team lead for your software organization for way less than minimum wage. 🙏🏻 Special thanks to James N, Lucy R, and Steve O for your support.

💼 Hire me as a Tech Creation Lead on your team. I have over 10 years development experience and would love to help your team reach their full potential. Head on over to https://damngood.tech/pages/schedule.html to schedule a free consultation.

--

--

Jordan H (Principal, Damn Good Tech) #openforwork

Senior Full Stack Developer & Tech Lead (#openforwork)