Created
July 20, 2012 18:06
-
-
Save hgdeoro/3152320 to your computer and use it in GitHub Desktop.
Django management command to assert all South migrations are applied
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
""" | |
Assert migrations are applied management command. | |
""" | |
import sys | |
from optparse import make_option | |
from django.core.management.base import BaseCommand | |
from django.conf import settings | |
from south import migration | |
from south.migration import Migrations | |
from south.exceptions import NoMigrations | |
from south.db import DEFAULT_DB_ALIAS | |
class Command(BaseCommand): | |
option_list = BaseCommand.option_list + ( | |
make_option('--all', action='store_true', dest='all_apps', default=False, | |
help='Run the specified migration for all apps.'), | |
make_option('--database', action='store', dest='database', | |
default=DEFAULT_DB_ALIAS, help='Nominates a database to synchronize. ' | |
'Defaults to the "default" database.'), | |
) | |
help = "Fails if any migration is pending" #@ReservedAssignment | |
args = "[appname] [migrationname|zero] [--all] [--database=dbalias]" | |
def handle(self, app=None, database=DEFAULT_DB_ALIAS, **options): | |
# NOTE: THIS IS DUPLICATED FROM django.core.management.commands.syncdb | |
# This code imports any module named 'management' in INSTALLED_APPS. | |
# The 'management' module is the preferred way of listening to post_syncdb | |
# signals, and since we're sending those out with create_table migrations, | |
# we need apps to behave correctly. | |
for app_name in settings.INSTALLED_APPS: | |
try: | |
__import__(app_name + '.management', {}, {}, ['']) | |
except ImportError, exc: | |
msg = exc.args[0] | |
if not msg.startswith('No module named') or 'management' not in msg: | |
raise | |
# END DJANGO DUPE CODE | |
# if all_apps flag is set, shift app over to target | |
if options.get('all_apps', False): | |
app = None | |
# Migrate each app | |
if app: | |
try: | |
apps = [Migrations(app)] | |
except NoMigrations: | |
print "The app '%s' does not appear to use migrations." % app | |
print "./manage.py migrate " + self.args | |
return | |
else: | |
apps = list(migration.all_migrations()) | |
assert_synced(apps, database, **options) | |
sys.exit(1) | |
def assert_synced(apps, database=DEFAULT_DB_ALIAS, **options): | |
""" | |
Assert all migrations are applied | |
""" | |
from south.models import MigrationHistory | |
applied_migrations = MigrationHistory.objects.filter(app_name__in=[app.app_label() for app in apps]) | |
if database != DEFAULT_DB_ALIAS: | |
applied_migrations = applied_migrations.using(database) | |
applied_migration_names = ['%s.%s' % (mi.app_name, mi.migration) for mi in applied_migrations] | |
res = [] | |
for app in apps: | |
print " " + app.app_label() | |
# Get the migrations object | |
for migration in app: | |
if migration.app_label() + "." + migration.name() in applied_migration_names: | |
applied_migration = applied_migrations.get(app_name=migration.app_label(), migration=migration.name()) | |
res += [format_migration_list_item(migration.name(), applied=applied_migration.applied, **options)] | |
else: | |
res += [format_migration_list_item(migration.name(), applied=False, **options)] | |
if False in res: | |
print "At least one migration isn't applied" | |
sys.exit(1) | |
sys.exit(0) | |
def format_migration_list_item(name, applied=True, **options): | |
if applied: | |
if int(options.get('verbosity')) >= 2: | |
print ' (*) %-80s (applied %s)' % (name, applied) | |
return True | |
else: | |
print ' (*) %s' % name | |
return True | |
else: | |
print ' ( ) %s' % name | |
return False |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is based on https://bitbucket.org/andrewgodwin/south/src/3f6f2066c47c/south/management/commands/migrate.py