There is an issue with migrations that crops up in a specific scenario in Django 1.7. While it is documented, we first became aware of it when doing a round of project upgrades to Django 1.8.

We recently made the jump to Django 1.8 on a number of projects. When we did this, we started to get this strange ProgrammingError exception when running our test suites. The error was complaining about a missing relation.

The team huddled on this topic. We had a few work arounds that got tests running and passing, got the sites running fine, but something didn't sit right. We needed to understand what was actually happening.

So we dug.

What we discovered was a documented issue and warning about migrations in Django 1.7 that led to situations where if you had a model in an app that didn't have migrations and had relationships to models in apps that did have migrations those models will be created through the old syncdb mechanism before migrations ran. When it did this, any foriegn key constraints to this apps under migration, would not be created.

The biggest example of this were apps not under migration that had ForeignKey references to auth.User.

At this point, you'd be left with a database without constraints that the models had defined. There is a level of checking and enforcing these constraints at the application level within Django, but it's always ideal to have them enforced in your database as well.

Later, when we upgraded to Django 1.8 and tried running the test suite, it was creating a database and running an updated migration process that had made this issue more apparent and put in the safeguard of raising the ProgrammingError.

The documentation suggests working around this issue by putting all apps under migrations and this is what we have started doing.

Put All Apps under Migrations

Make sure all apps in your INSTALLED_APPS have migrations. This is straight-forward with the apps in your project, but you don't control the third-party apps you might be using.

You can use the MIGRATION_MODULES setting to specify where the migrations should be stored and then you can add them. This has the added benefit of allowing you to track and migrate during upgrades of third-party apps that are not shipping with migrations.