Automation is the key to catching this.
In Django the rules of what does and does not require a migration seem entirely arbitrary to me in. For starters I always forget that
verbose_name requires one. Then at some point down the road, I discover that I have missed a migration in a earlier commit. I then need to get my git-foo on to tidy things up. Here is how I use automation to solve this issue.
A little help from makemigrations
I run this in my CI environment in Django 1.9.
$ ./manage.py makemigrations --dry-run --no-input | grep 'No changes detected' || exit 1
--dry-runprints what it will do.
--no-inputskips the stale content types input prompt.
Then I grep for the “No changes detected” string in the output, if it isn’t, I exit
Once I make the move to Django 1.10, things become even easier with the new
--check option on
$ ./manage.py makemigrations --check --dry-run
This exits with a non-zero error code if there are outstanding migrations. [docs]
CI or as a Unit Test?
If this is a major concern you can run this as a unit test (pytest example):
import pytest from django.core.management import call_command def test_no_missing_migrations(): with pytest.raises(SystemExit) as e: call_command( 'makemigrations', interactive=False, check=True, dry_run=True, ) assert str(e.value) == '1'
Personally, I did not want to run this check when running my tests, the call to
makemigrations is somewhat slow (in my case 8 seconds) and my project test suite is still small and fast with only taking 3-4 seconds. I did not want to triple my test suite runtime just for this check.