Esempio n. 1
0
 def emit_post_migrate(verbosity, interactive, database):
     # Emit the post migrate signal. This allows individual applications to
     # respond as if the database had been migrated from scratch.
     all_models = []
     for app_config in app_cache.get_app_configs(only_with_models_module=True):
         all_models.extend(router.get_migratable_models(app_config.models_module, database, include_auto_created=True))
     emit_post_migrate_signal(set(all_models), verbosity, interactive, database)
Esempio n. 2
0
 def load_disk(self):
     """
     Loads the migrations from all INSTALLED_APPS from disk.
     """
     self.disk_migrations = {}
     self.unmigrated_apps = set()
     self.migrated_apps = set()
     for app_config in app_cache.get_app_configs(only_with_models_module=True):
         # Get the migrations module directory
         module_name = self.migrations_module(app_config.label)
         was_loaded = module_name in sys.modules
         try:
             module = import_module(module_name)
         except ImportError as e:
             # I hate doing this, but I don't want to squash other import errors.
             # Might be better to try a directory check directly.
             if "No module named" in str(e) and "migrations" in str(e):
                 self.unmigrated_apps.add(app_config.label)
                 continue
             raise
         else:
             # PY3 will happily import empty dirs as namespaces.
             if not hasattr(module, '__file__'):
                 continue
             # Module is not a package (e.g. migrations.py).
             if not hasattr(module, '__path__'):
                 continue
             # Force a reload if it's already loaded (tests need this)
             if was_loaded:
                 six.moves.reload_module(module)
         self.migrated_apps.add(app_config.label)
         directory = os.path.dirname(module.__file__)
         # Scan for .py[c|o] files
         migration_names = set()
         for name in os.listdir(directory):
             if name.endswith(".py") or name.endswith(".pyc") or name.endswith(".pyo"):
                 import_name = name.rsplit(".", 1)[0]
                 if import_name[0] not in "_.~":
                     migration_names.add(import_name)
         # Load them
         south_style_migrations = False
         for migration_name in migration_names:
             try:
                 migration_module = import_module("%s.%s" % (module_name, migration_name))
             except ImportError as e:
                 # Ignore South import errors, as we're triggering them
                 if "south" in str(e).lower():
                     south_style_migrations = True
                     break
                 raise
             if not hasattr(migration_module, "Migration"):
                 raise BadMigrationError("Migration %s in app %s has no Migration class" % (migration_name, app_config.label))
             # Ignore South-style migrations
             if hasattr(migration_module.Migration, "forwards"):
                 south_style_migrations = True
                 break
             self.disk_migrations[app_config.label, migration_name] = migration_module.Migration(migration_name, app_config.label)
         if south_style_migrations:
             self.unmigrated_apps.add(app_config.label)
Esempio n. 3
0
def emit_post_migrate_signal(created_models, verbosity, interactive, db):
    # Emit the post_migrate signal for every application.
    for app_config in app_cache.get_app_configs(only_with_models_module=True):
        if verbosity >= 2:
            print("Running post-migrate handlers for application %s" % app_config.label)
        models.signals.post_migrate.send(
            sender=app_config.models_module,
            app=app_config.models_module,
            created_models=created_models,
            verbosity=verbosity,
            interactive=interactive,
            db=db)
Esempio n. 4
0
    def fixture_dirs(self):
        """
        Return a list of fixture directories.

        The list contains the 'fixtures' subdirectory of each installed
        application, if it exists, the directories in FIXTURE_DIRS, and the
        current directory.
        """
        dirs = []
        for app_config in app_cache.get_app_configs():
            d = os.path.join(app_config.path, 'fixtures')
            if os.path.isdir(d):
                dirs.append(d)
        dirs.extend(list(settings.FIXTURE_DIRS))
        dirs.append('')
        dirs = [upath(os.path.abspath(os.path.realpath(d))) for d in dirs]
        return dirs
Esempio n. 5
0
    def build_suite(self, test_labels, extra_tests=None, **kwargs):
        suite = unittest.TestSuite()

        if test_labels:
            for label in test_labels:
                if '.' in label:
                    suite.addTest(build_test(label))
                else:
                    app_config = app_cache.get_app_config(label)
                    suite.addTest(build_suite(app_config))
        else:
            for app_config in app_cache.get_app_configs():
                suite.addTest(build_suite(app_config))

        if extra_tests:
            for test in extra_tests:
                suite.addTest(test)

        return runner.reorder_suite(suite, (unittest.TestCase,))
Esempio n. 6
0
    def handle(self, *app_labels, **options):
        from django.core.apps import app_cache

        format = options.get('format')
        indent = options.get('indent')
        using = options.get('database')
        excludes = options.get('exclude')
        show_traceback = options.get('traceback')
        use_natural_keys = options.get('use_natural_keys')
        if use_natural_keys:
            warnings.warn("``--natural`` is deprecated; use ``--natural-foreign`` instead.",
                PendingDeprecationWarning)
        use_natural_foreign_keys = options.get('use_natural_foreign_keys') or use_natural_keys
        use_natural_primary_keys = options.get('use_natural_primary_keys')
        use_base_manager = options.get('use_base_manager')
        pks = options.get('primary_keys')

        if pks:
            primary_keys = pks.split(',')
        else:
            primary_keys = []

        excluded_apps = set()
        excluded_models = set()
        for exclude in excludes:
            if '.' in exclude:
                app_label, model_name = exclude.split('.', 1)
                model_obj = app_cache.get_model(app_label, model_name)
                if not model_obj:
                    raise CommandError('Unknown model in excludes: %s' % exclude)
                excluded_models.add(model_obj)
            else:
                try:
                    app_obj = app_cache.get_app_config(exclude).models_module
                    if app_obj is not None:
                        excluded_apps.add(app_obj)
                except LookupError:
                    raise CommandError('Unknown app in excludes: %s' % exclude)

        if len(app_labels) == 0:
            if primary_keys:
                raise CommandError("You can only use --pks option with one model")
            app_list = OrderedDict((app_config.models_module, None)
                for app_config in app_cache.get_app_configs(only_with_models_module=True)
                if app_config.models_module not in excluded_apps)
        else:
            if len(app_labels) > 1 and primary_keys:
                raise CommandError("You can only use --pks option with one model")
            app_list = OrderedDict()
            for label in app_labels:
                try:
                    app_label, model_label = label.split('.')
                    try:
                        app = app_cache.get_app_config(app_label).models_module
                    except LookupError:
                        raise CommandError("Unknown application: %s" % app_label)
                    if app is None or app in excluded_apps:
                        continue
                    model = app_cache.get_model(app_label, model_label)
                    if model is None:
                        raise CommandError("Unknown model: %s.%s" % (app_label, model_label))

                    if app in app_list.keys():
                        if app_list[app] and model not in app_list[app]:
                            app_list[app].append(model)
                    else:
                        app_list[app] = [model]
                except ValueError:
                    if primary_keys:
                        raise CommandError("You can only use --pks option with one model")
                    # This is just an app - no model qualifier
                    app_label = label
                    try:
                        app = app_cache.get_app_config(app_label).models_module
                    except LookupError:
                        raise CommandError("Unknown application: %s" % app_label)
                    if app is None or app in excluded_apps:
                        continue
                    app_list[app] = None

        # Check that the serialization format exists; this is a shortcut to
        # avoid collating all the objects and _then_ failing.
        if format not in serializers.get_public_serializer_formats():
            try:
                serializers.get_serializer(format)
            except serializers.SerializerDoesNotExist:
                pass

            raise CommandError("Unknown serialization format: %s" % format)

        def get_objects():
            # Collate the objects to be serialized.
            for model in sort_dependencies(app_list.items()):
                if model in excluded_models:
                    continue
                if not model._meta.proxy and router.allow_migrate(using, model):
                    if use_base_manager:
                        objects = model._base_manager
                    else:
                        objects = model._default_manager

                    queryset = objects.using(using).order_by(model._meta.pk.name)
                    if primary_keys:
                        queryset = queryset.filter(pk__in=primary_keys)
                    for obj in queryset.iterator():
                        yield obj

        try:
            self.stdout.ending = None
            serializers.serialize(format, get_objects(), indent=indent,
                    use_natural_foreign_keys=use_natural_foreign_keys,
                    use_natural_primary_keys=use_natural_primary_keys,
                    stream=self.stdout)
        except Exception as e:
            if show_traceback:
                raise
            raise CommandError("Unable to serialize database: %s" % e)
Esempio n. 7
0
def get_installed():
    from django.core.apps import app_cache
    return [app_config.name for app_config in app_cache.get_app_configs()]
Esempio n. 8
0
def update_all_contenttypes(verbosity=2, **kwargs):
    for app_config in app_cache.get_app_configs(only_with_models_module=True):
        update_contenttypes(app_config.models_module, None, verbosity, **kwargs)
Esempio n. 9
0
    def sync_apps(self, connection, apps):
        "Runs the old syncdb-style operation on a list of apps."
        cursor = connection.cursor()

        # Get a list of already installed *models* so that references work right.
        tables = connection.introspection.table_names()
        seen_models = connection.introspection.installed_models(tables)
        created_models = set()
        pending_references = {}

        # Build the manifest of apps and models that are to be synchronized
        all_models = [
            (app_config.label,
                router.get_migratable_models(app_config.models_module, connection.alias, include_auto_created=True))
            for app_config in app_cache.get_app_configs(only_with_models_module=True)
            if app_config.label in apps
        ]

        def model_installed(model):
            opts = model._meta
            converter = connection.introspection.table_name_converter
            # Note that if a model is unmanaged we short-circuit and never try to install it
            return not ((converter(opts.db_table) in tables) or
                (opts.auto_created and converter(opts.auto_created._meta.db_table) in tables))

        manifest = OrderedDict(
            (app_name, list(filter(model_installed, model_list)))
            for app_name, model_list in all_models
        )

        create_models = set(itertools.chain(*manifest.values()))
        emit_pre_migrate_signal(create_models, self.verbosity, self.interactive, connection.alias)

        # Create the tables for each model
        if self.verbosity >= 1:
            self.stdout.write("  Creating tables...\n")
        with transaction.atomic(using=connection.alias, savepoint=False):
            for app_name, model_list in manifest.items():
                for model in model_list:
                    # Create the model's database table, if it doesn't already exist.
                    if self.verbosity >= 3:
                        self.stdout.write("    Processing %s.%s model\n" % (app_name, model._meta.object_name))
                    sql, references = connection.creation.sql_create_model(model, no_style(), seen_models)
                    seen_models.add(model)
                    created_models.add(model)
                    for refto, refs in references.items():
                        pending_references.setdefault(refto, []).extend(refs)
                        if refto in seen_models:
                            sql.extend(connection.creation.sql_for_pending_references(refto, no_style(), pending_references))
                    sql.extend(connection.creation.sql_for_pending_references(model, no_style(), pending_references))
                    if self.verbosity >= 1 and sql:
                        self.stdout.write("    Creating table %s\n" % model._meta.db_table)
                    for statement in sql:
                        cursor.execute(statement)
                    tables.append(connection.introspection.table_name_converter(model._meta.db_table))

        # We force a commit here, as that was the previous behaviour.
        # If you can prove we don't need this, remove it.
        transaction.set_dirty(using=connection.alias)

        # The connection may have been closed by a syncdb handler.
        cursor = connection.cursor()

        # Install custom SQL for the app (but only if this
        # is a model we've just created)
        if self.verbosity >= 1:
            self.stdout.write("  Installing custom SQL...\n")
        for app_name, model_list in manifest.items():
            for model in model_list:
                if model in created_models:
                    custom_sql = custom_sql_for_model(model, no_style(), connection)
                    if custom_sql:
                        if self.verbosity >= 2:
                            self.stdout.write("    Installing custom SQL for %s.%s model\n" % (app_name, model._meta.object_name))
                        try:
                            with transaction.commit_on_success_unless_managed(using=connection.alias):
                                for sql in custom_sql:
                                    cursor.execute(sql)
                        except Exception as e:
                            self.stderr.write("    Failed to install custom SQL for %s.%s model: %s\n" % (app_name, model._meta.object_name, e))
                            if self.show_traceback:
                                traceback.print_exc()
                    else:
                        if self.verbosity >= 3:
                            self.stdout.write("    No custom SQL for %s.%s model\n" % (app_name, model._meta.object_name))

        if self.verbosity >= 1:
            self.stdout.write("  Installing indexes...\n")

        # Install SQL indices for all newly created models
        for app_name, model_list in manifest.items():
            for model in model_list:
                if model in created_models:
                    index_sql = connection.creation.sql_indexes_for_model(model, no_style())
                    if index_sql:
                        if self.verbosity >= 2:
                            self.stdout.write("    Installing index for %s.%s model\n" % (app_name, model._meta.object_name))
                        try:
                            with transaction.commit_on_success_unless_managed(using=connection.alias):
                                for sql in index_sql:
                                    cursor.execute(sql)
                        except Exception as e:
                            self.stderr.write("    Failed to install index for %s.%s model: %s\n" % (app_name, model._meta.object_name, e))

        # Load initial_data fixtures (unless that has been disabled)
        if self.load_initial_data:
            call_command('loaddata', 'initial_data', verbosity=self.verbosity, database=connection.alias, skip_validation=True)

        return created_models