from django.core.exceptions import ImproperlyConfigured from django.core.management import call_command, CommandError from django.core.management.base import BaseCommand from django.conf import settings from django.db.models import loading from django.test import simple from south.migration import Migrations from south.exceptions import NoMigrations from south.hacks import hacks class Command(BaseCommand): help = "Runs migrations for each app in turn, detecting missing depends_on values." usage_str = "Usage: ./manage.py migrationcheck" def handle(self, check_app_name=None, **options): runner = simple.DjangoTestSuiteRunner(verbosity=0) err_msg = "Failed to migrate %s; see output for hints at missing dependencies:\n" hacks.patch_flush_during_test_db_creation() failures = 0 if check_app_name is None: app_names = settings.INSTALLED_APPS else: app_names = [check_app_name] for app_name in app_names: app_label = app_name.split(".")[-1] if app_name == 'south': continue try: Migrations(app_name) except (NoMigrations, ImproperlyConfigured): continue app = loading.get_app(app_label) verbosity = int(options.get('verbosity', 1)) if verbosity >= 1: self.stderr.write("processing %s\n" % app_name) old_config = runner.setup_databases() try: call_command('migrate', app_label, noinput=True, verbosity=verbosity) for model in loading.get_models(app): dummy = model._default_manager.exists() except (KeyboardInterrupt, SystemExit): raise except Exception as e: failures += 1 if verbosity >= 1: self.stderr.write(err_msg % app_name) self.stderr.write("%s\n" % e) finally: runner.teardown_databases(old_config) if failures > 0: raise CommandError("Missing depends_on found in %s app(s)." % failures) self.stderr.write("No missing depends_on found.\n") # #for each app: # start with blank db. # syncdb only south (and contrib?) # # migrate a single app all the way up. any errors is missing depends_on. # for all models of that app, try the default manager: # from django.db.models import loading # for m in loading.get_models(loading.get_app('a')): # m._default_manager.exists() # Any error is also a missing depends on.