Skip to content

Instantly share code, notes, and snippets.

@nealtodd
Created June 10, 2015 11:10
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save nealtodd/a8f87b0d95e73eb482c5 to your computer and use it in GitHub Desktop.
Save nealtodd/a8f87b0d95e73eb482c5 to your computer and use it in GitHub Desktop.
Django management command to detect missing migration files.
import sys
from django.apps import apps
from django.conf import settings
from django.core.management.base import BaseCommand
from django.db import connections
from django.db.migrations.autodetector import MigrationAutodetector
from django.db.migrations.executor import MigrationExecutor
from django.db.migrations.state import ProjectState
from django.db.utils import OperationalError
class Command(BaseCommand):
"""
Detect if any apps have missing migration files
(not necessaily applied though)
"""
help = "Detect if any apps have missing migration files"
def handle(self, *args, **kwargs):
changed = set()
self.stdout.write("Checking...")
for db in settings.DATABASES.keys():
try:
executor = MigrationExecutor(connections[db])
except OperationalError:
sys.exit("Unable to check migrations: cannot connect to database\n")
autodetector = MigrationAutodetector(
executor.loader.project_state(),
ProjectState.from_apps(apps),
)
changed.update(autodetector.changes(graph=executor.loader.graph).keys())
if changed:
sys.exit("Apps with model changes but no corresponding migration file: %(changed)s\n" % {
'changed': list(changed)
})
else:
sys.stdout.write("All migration files present\n")
@nealtodd
Copy link
Author

Useful as part of a Continuous Integration system, to alert when makemigrations needs to be run. (Or standalone, or part of a Fabric deployment process for example.)

For CI setup it just needs an empty database created for each database defined in settings.DATABASES (that's in addition to the equivalent test databases the test suite creates).

The need for a migration can easily be missed with Django's native Migrations because there are may more minor model changes that require one, which a developer might forget about (e.g. a field label or help_text edit).

@fjsj
Copy link

fjsj commented May 2, 2016

great command @nealtood! forked it to allow ignoring some apps (useful for ignoring some third-party ones): https://gist.github.com/fjsj/3df250b88c0163fd661dfc4d6d67877f

@clintonb
Copy link

As of Django 1.10, you can run ./manage.py makemigrations --check to detect missing migrations. See https://docs.djangoproject.com/en/1.11/ref/django-admin/#cmdoption-makemigrations-check.

@frnhr
Copy link

frnhr commented Jul 6, 2017

To only detect and not actually create them: ./manage.py makemigrations --check --dry-run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment