Python源码示例:django.db.migrations.loader.MigrationLoader()

示例1
def test_total_deconstruct(self):
        loader = MigrationLoader(None, load=True, ignore_no_migrations=True)
        loader.disk_migrations = {t: v for t, v in loader.disk_migrations.items() if t[0] != 'testapp'}
        app_labels = {"testapp"}
        questioner = NonInteractiveMigrationQuestioner(specified_apps=app_labels, dry_run=True)
        autodetector = MigrationAutodetector(
            loader.project_state(),
            ProjectState.from_apps(apps),
            questioner,
        )
        # Detect changes
        changes = autodetector.changes(
            graph=loader.graph,
            trim_to_apps=app_labels or None,
            convert_apps=app_labels or None,
            migration_name="my_fake_migration_for_test_deconstruct",
        )
        self.assertGreater(len(changes), 0)
        for app_label, app_migrations in changes.items():
            for migration in app_migrations:
                # Describe the migration
                writer = MigrationWriter(migration)

                migration_string = writer.as_string()
                self.assertNotEqual(migration_string, "") 
示例2
def get_migration_levels(self):
        connection = connections[DEFAULT_DB_ALIAS]
        loader = MigrationLoader(connection, ignore_no_migrations=True)
        graph = loader.graph
        app_names = sorted(loader.migrated_apps)
        last_migrations = {}
        for app_name in app_names:
            shown = set()
            for node in graph.leaf_nodes(app_name):
                for plan_node in graph.forwards_plan(node):
                    if plan_node not in shown and plan_node[0] == app_name:
                        # Give it a nice title if it's a squashed one
                        title = plan_node[1]
                        if graph.nodes[plan_node].replaces:
                            title += " (%s squashed migrations)" % len(graph.nodes[plan_node].replaces)
                        # Mark it as applied/unapplied
                        if plan_node in loader.applied_migrations:
                            shown.add(plan_node)
                            last_migrations[app_name] = int(plan_node[1].split('_')[0])
                        else:
                            continue
        connection.close()
        return last_migrations 
示例3
def test_first_dependency(self):
        """
        A dependency to an app with no migrations uses __first__.
        """
        # Load graph
        loader = MigrationLoader(connection)
        before = self.make_project_state([])
        after = self.make_project_state([self.book_migrations_fk])
        after.real_apps = ["migrations"]
        autodetector = MigrationAutodetector(before, after)
        changes = autodetector._detect_changes(graph=loader.graph)
        # Right number/type of migrations?
        self.assertNumberMigrations(changes, 'otherapp', 1)
        self.assertOperationTypes(changes, 'otherapp', 0, ["CreateModel"])
        self.assertOperationAttributes(changes, 'otherapp', 0, 0, name="Book")
        self.assertMigrationDependencies(changes, 'otherapp', 0, [("migrations", "__first__")]) 
示例4
def test_last_dependency(self):
        """
        A dependency to an app with existing migrations uses the
        last migration of that app.
        """
        # Load graph
        loader = MigrationLoader(connection)
        before = self.make_project_state([])
        after = self.make_project_state([self.book_migrations_fk])
        after.real_apps = ["migrations"]
        autodetector = MigrationAutodetector(before, after)
        changes = autodetector._detect_changes(graph=loader.graph)
        # Right number/type of migrations?
        self.assertNumberMigrations(changes, 'otherapp', 1)
        self.assertOperationTypes(changes, 'otherapp', 0, ["CreateModel"])
        self.assertOperationAttributes(changes, 'otherapp', 0, 0, name="Book")
        self.assertMigrationDependencies(changes, 'otherapp', 0, [("migrations", "0002_second")]) 
示例5
def test_first_dependency(self):
        """
        A dependency to an app with no migrations uses __first__.
        """
        # Load graph
        loader = MigrationLoader(connection)
        before = self.make_project_state([])
        after = self.make_project_state([self.book_migrations_fk])
        after.real_apps = ["migrations"]
        autodetector = MigrationAutodetector(before, after)
        changes = autodetector._detect_changes(graph=loader.graph)
        # Right number/type of migrations?
        self.assertNumberMigrations(changes, 'otherapp', 1)
        self.assertOperationTypes(changes, 'otherapp', 0, ["CreateModel"])
        self.assertOperationAttributes(changes, 'otherapp', 0, 0, name="Book")
        self.assertMigrationDependencies(changes, 'otherapp', 0, [("migrations", "__first__")]) 
示例6
def test_last_dependency(self):
        """
        A dependency to an app with existing migrations uses the
        last migration of that app.
        """
        # Load graph
        loader = MigrationLoader(connection)
        before = self.make_project_state([])
        after = self.make_project_state([self.book_migrations_fk])
        after.real_apps = ["migrations"]
        autodetector = MigrationAutodetector(before, after)
        changes = autodetector._detect_changes(graph=loader.graph)
        # Right number/type of migrations?
        self.assertNumberMigrations(changes, 'otherapp', 1)
        self.assertOperationTypes(changes, 'otherapp', 0, ["CreateModel"])
        self.assertOperationAttributes(changes, 'otherapp', 0, 0, name="Book")
        self.assertMigrationDependencies(changes, 'otherapp', 0, [("migrations", "0002_second")]) 
示例7
def test_first_dependency(self):
        """
        A dependency to an app with no migrations uses __first__.
        """
        # Load graph
        loader = MigrationLoader(connection)
        before = self.make_project_state([])
        after = self.make_project_state([self.book_migrations_fk])
        after.real_apps = ["migrations"]
        autodetector = MigrationAutodetector(before, after)
        changes = autodetector._detect_changes(graph=loader.graph)
        # Right number/type of migrations?
        self.assertNumberMigrations(changes, 'otherapp', 1)
        self.assertOperationTypes(changes, 'otherapp', 0, ["CreateModel"])
        self.assertOperationAttributes(changes, 'otherapp', 0, 0, name="Book")
        self.assertMigrationDependencies(changes, 'otherapp', 0, [("migrations", "__first__")]) 
示例8
def test_last_dependency(self):
        """
        A dependency to an app with existing migrations uses the
        last migration of that app.
        """
        # Load graph
        loader = MigrationLoader(connection)
        before = self.make_project_state([])
        after = self.make_project_state([self.book_migrations_fk])
        after.real_apps = ["migrations"]
        autodetector = MigrationAutodetector(before, after)
        changes = autodetector._detect_changes(graph=loader.graph)
        # Right number/type of migrations?
        self.assertNumberMigrations(changes, 'otherapp', 1)
        self.assertOperationTypes(changes, 'otherapp', 0, ["CreateModel"])
        self.assertOperationAttributes(changes, 'otherapp', 0, 0, name="Book")
        self.assertMigrationDependencies(changes, 'otherapp', 0, [("migrations", "0002_second")]) 
示例9
def serialize_db_to_string(self):
        """
        Serializes all data in the database into a JSON string.
        Designed only for test runner usage; will not handle large
        amounts of data.
        """
        # Build list of all apps to serialize
        from django.db.migrations.loader import MigrationLoader
        loader = MigrationLoader(self.connection)
        app_list = []
        for app_config in apps.get_app_configs():
            if (
                app_config.models_module is not None and
                app_config.label in loader.migrated_apps and
                app_config.name not in settings.TEST_NON_SERIALIZED_APPS
            ):
                app_list.append((app_config, None))

        # Make a function to iteratively return every object
        def get_objects():
            for model in serializers.sort_dependencies(app_list):
                if (not model._meta.proxy and model._meta.managed and
                        router.allow_migrate_model(self.connection.alias, model)):
                    queryset = model._default_manager.using(self.connection.alias).order_by(model._meta.pk.name)
                    for obj in queryset.iterator():
                        yield obj
        # Serialize to a string
        out = StringIO()
        serializers.serialize("json", get_objects(), indent=None, stream=out)
        return out.getvalue() 
示例10
def show_list(self, connection, app_names=None):
        """
        Shows a list of all migrations on the system, or only those of
        some named apps.
        """
        # Load migrations from disk/DB
        loader = MigrationLoader(connection, ignore_no_migrations=True)
        graph = loader.graph
        # If we were passed a list of apps, validate it
        if app_names:
            invalid_apps = []
            for app_name in app_names:
                if app_name not in loader.migrated_apps:
                    invalid_apps.append(app_name)
            if invalid_apps:
                raise CommandError("No migrations present for: %s" % (", ".join(invalid_apps)))
        # Otherwise, show all apps in alphabetic order
        else:
            app_names = sorted(loader.migrated_apps)
        # For each app, print its migrations in order from oldest (roots) to
        # newest (leaves).
        for app_name in app_names:
            self.stdout.write(app_name, self.style.MIGRATE_LABEL)
            shown = set()
            for node in graph.leaf_nodes(app_name):
                for plan_node in graph.forwards_plan(node):
                    if plan_node not in shown and plan_node[0] == app_name:
                        # Give it a nice title if it's a squashed one
                        title = plan_node[1]
                        if graph.nodes[plan_node].replaces:
                            title += " (%s squashed migrations)" % len(graph.nodes[plan_node].replaces)
                        # Mark it as applied/unapplied
                        if plan_node in loader.applied_migrations:
                            self.stdout.write(" [X] %s" % title)
                        else:
                            self.stdout.write(" [ ] %s" % title)
                        shown.add(plan_node)
            # If we didn't print anything, then a small message
            if not shown:
                self.stdout.write(" (no migrations)", self.style.MIGRATE_FAILURE) 
示例11
def show_plan(self, connection):
        """
        Shows all known migrations in the order they will be applied
        """
        # Load migrations from disk/DB
        loader = MigrationLoader(connection)
        graph = loader.graph
        targets = graph.leaf_nodes()
        plan = []
        seen = set()

        # Generate the plan
        for target in targets:
            for migration in graph.forwards_plan(target):
                if migration not in seen:
                    plan.append(graph.nodes[migration])
                    seen.add(migration)

        # Output
        def print_deps(migration):
            out = []
            for dep in migration.dependencies:
                if dep[1] == "__first__":
                    roots = graph.root_nodes(dep[0])
                    dep = roots[0] if roots else (dep[0], "__first__")
                out.append("%s.%s" % dep)
            if out:
                return " ... (%s)" % ", ".join(out)
            return ""

        for migration in plan:
            deps = ""
            if self.verbosity >= 2:
                deps = print_deps(migration)
            if (migration.app_label, migration.name) in loader.applied_migrations:
                self.stdout.write("[X]  %s%s" % (migration, deps))
            else:
                self.stdout.write("[ ]  %s%s" % (migration, deps)) 
示例12
def check_for_migrations(app_config, connection):
    # Inner import, else tests imports it too early as it needs settings
    from django.db.migrations.loader import MigrationLoader
    loader = MigrationLoader(connection)
    if app_config.label in loader.migrated_apps:
        raise CommandError(
            "App '%s' has migrations. Only the sqlmigrate and sqlflush commands "
            "can be used when an app has migrations." % app_config.label
        ) 
示例13
def _get_apps_for_migration(self, migration_states):
        loader = MigrationLoader(connection)
        full_names = []
        for app_name, migration_name in migration_states:
            if migration_name != 'zero':
                migration_name = loader.get_migration_by_prefix(app_name, migration_name).name
                full_names.append((app_name, migration_name))
        state = loader.project_state(full_names)
        if django.VERSION < (1, 8):
            state.render()
        return state.apps 
示例14
def all_migrations(
    database: str = DEFAULT_DB_ALIAS,
    app_names: Optional[List[str]] = None,
) -> List[Node]:
    """
    Returns the sorted list of migrations nodes.

    The order is the same as when migrations are applied.

    When you might need this function?
    When you are testing the migration order.

    For example, imagine that you have a direct dependency:
    ``main_app.0002_migration`` and ``other_app.0001_initial``
    where ``other_app.0001_initial`` relies on the model or field
    introduced in ``main_app.0002_migration``.

    You can use ``dependencies`` field
    to ensure that everything works correctly.

    But, sometimes migrations are squashed,
    sometimes they are renamed, refactored, and moved.

    It would be better to have a test that will ensure
    that ``other_app.0001_initial`` comes after ``main_app.0002_migration``.
    And everything works as expected.
    """
    loader = MigrationLoader(connections[database])

    if app_names:
        _validate_app_names(app_names)
        targets = [
            key
            for key in loader.graph.leaf_nodes()
            if key[0] in app_names
        ]
    else:
        targets = loader.graph.leaf_nodes()
    return _generate_plan(targets, loader) 
示例15
def _generate_plan(
    targets: List[Node],
    loader: MigrationLoader,
) -> List[Node]:
    plan = []
    seen: Set[Node] = set()

    # Generate the plan
    for target in targets:
        for migration in loader.graph.forwards_plan(target):
            if migration not in seen:
                node = loader.graph.node_map[migration]
                plan.append(node)
                seen.add(migration)
    return plan 
示例16
def serialize_db_to_string(self):
        """
        Serialize all data in the database into a JSON string.
        Designed only for test runner usage; will not handle large
        amounts of data.
        """
        # Build list of all apps to serialize
        from django.db.migrations.loader import MigrationLoader
        loader = MigrationLoader(self.connection)
        app_list = []
        for app_config in apps.get_app_configs():
            if (
                app_config.models_module is not None and
                app_config.label in loader.migrated_apps and
                app_config.name not in settings.TEST_NON_SERIALIZED_APPS
            ):
                app_list.append((app_config, None))

        # Make a function to iteratively return every object
        def get_objects():
            for model in serializers.sort_dependencies(app_list):
                if (model._meta.can_migrate(self.connection) and
                        router.allow_migrate_model(self.connection.alias, model)):
                    queryset = model._default_manager.using(self.connection.alias).order_by(model._meta.pk.name)
                    yield from queryset.iterator()
        # Serialize to a string
        out = StringIO()
        serializers.serialize("json", get_objects(), indent=None, stream=out)
        return out.getvalue() 
示例17
def _get_apps_for_migration(self, migration_states):
        loader = MigrationLoader(connection)
        full_names = []
        for app_name, migration_name in migration_states:
            if migration_name != 'zero':
                migration_name = loader.get_migration_by_prefix(
                    app_name, migration_name).name
                full_names.append((app_name, migration_name))
        state = loader.project_state(full_names)
        return state.apps 
示例18
def _get_apps_for_migration(self, migration_states):
        loader = MigrationLoader(connection)
        full_names = []
        for app_name, migration_name in migration_states:
            if migration_name != 'zero':
                migration_name = loader.get_migration_by_prefix(
                    app_name, migration_name).name
                full_names.append((app_name, migration_name))
        state = loader.project_state(full_names)
        return state.apps 
示例19
def check_migrations_applied(app_configs, **kwargs):
    """
    A Django check to see if all migrations have been applied correctly.
    """
    from django.db.migrations.loader import MigrationLoader

    errors = []

    # Load migrations from disk/DB
    try:
        loader = MigrationLoader(connection, ignore_no_migrations=True)
    except (ImproperlyConfigured, ProgrammingError, OperationalError):
        msg = "Can't connect to database to check migrations"
        return [checks.Info(msg, id=health.INFO_CANT_CHECK_MIGRATIONS)]

    if app_configs:
        app_labels = [app.label for app in app_configs]
    else:
        app_labels = loader.migrated_apps

    for node, migration in loader.graph.nodes.items():
        if migration.app_label not in app_labels:
            continue
        if node not in loader.applied_migrations:
            msg = "Unapplied migration {}".format(migration)
            # NB: This *must* be a Warning, not an Error, because Errors
            # prevent migrations from being run.
            errors.append(checks.Warning(msg, id=health.WARNING_UNAPPLIED_MIGRATION))

    return errors 
示例20
def serialize_db_to_string(self):
        """
        Serialize all data in the database into a JSON string.
        Designed only for test runner usage; will not handle large
        amounts of data.
        """
        # Build list of all apps to serialize
        from django.db.migrations.loader import MigrationLoader
        loader = MigrationLoader(self.connection)
        app_list = []
        for app_config in apps.get_app_configs():
            if (
                app_config.models_module is not None and
                app_config.label in loader.migrated_apps and
                app_config.name not in settings.TEST_NON_SERIALIZED_APPS
            ):
                app_list.append((app_config, None))

        # Make a function to iteratively return every object
        def get_objects():
            for model in serializers.sort_dependencies(app_list):
                if (model._meta.can_migrate(self.connection) and
                        router.allow_migrate_model(self.connection.alias, model)):
                    queryset = model._default_manager.using(self.connection.alias).order_by(model._meta.pk.name)
                    yield from queryset.iterator()
        # Serialize to a string
        out = StringIO()
        serializers.serialize("json", get_objects(), indent=None, stream=out)
        return out.getvalue() 
示例21
def test__migrations(self):
        app_labels = set(app.label for app in apps.get_app_configs()
                         if app.name.startswith('wagtail.'))
        for app_label in app_labels:
            apps.get_app_config(app_label.split('.')[-1])
        loader = MigrationLoader(None, ignore_no_migrations=True)

        conflicts = dict(
            (app_label, conflict)
            for app_label, conflict in loader.detect_conflicts().items()
            if app_label in app_labels
        )

        if conflicts:
            name_str = "; ".join("%s in %s" % (", ".join(names), app)
                                 for app, names in conflicts.items())
            self.fail("Conflicting migrations detected (%s)." % name_str)

        autodetector = MigrationAutodetector(
            loader.project_state(),
            ProjectState.from_apps(apps),
            MigrationQuestioner(specified_apps=app_labels, dry_run=True),
        )

        changes = autodetector.changes(
            graph=loader.graph,
            trim_to_apps=app_labels or None,
            convert_apps=app_labels or None,
        )

        if changes:
            migrations = '\n'.join((
                '  {migration}\n{changes}'.format(
                    migration=migration,
                    changes='\n'.join('    {0}'.format(operation.describe())
                                      for operation in migration.operations))
                for (_, migrations) in changes.items()
                for migration in migrations))

            self.fail('Model changes with no migrations detected:\n%s' % migrations) 
示例22
def serialize_db_to_string(self):
        """
        Serializes all data in the database into a JSON string.
        Designed only for test runner usage; will not handle large
        amounts of data.
        """
        # Build list of all apps to serialize
        from django.db.migrations.loader import MigrationLoader
        loader = MigrationLoader(self.connection)
        app_list = []
        for app_config in apps.get_app_configs():
            if (
                app_config.models_module is not None and
                app_config.label in loader.migrated_apps and
                app_config.name not in settings.TEST_NON_SERIALIZED_APPS
            ):
                app_list.append((app_config, None))

        # Make a function to iteratively return every object
        def get_objects():
            for model in serializers.sort_dependencies(app_list):
                if (model._meta.can_migrate(self.connection) and
                        router.allow_migrate_model(self.connection.alias, model)):
                    queryset = model._default_manager.using(self.connection.alias).order_by(model._meta.pk.name)
                    for obj in queryset.iterator():
                        yield obj
        # Serialize to a string
        out = StringIO()
        serializers.serialize("json", get_objects(), indent=None, stream=out)
        return out.getvalue() 
示例23
def log_last_migration(cls):
        """Parses the applied migrations dictionary to log the last applied migration."""
        loader = MigrationLoader(connection)
        api_migrations = [
            migration for app, migration in loader.applied_migrations if app == cls.app
        ]
        last_migration = max(api_migrations, key=lambda name: int(name[:4]))
        log.info(f"The last applied migration: {last_migration}") 
示例24
def serialize_db_to_string(self):
        """
        Serializes all data in the database into a JSON string.
        Designed only for test runner usage; will not handle large
        amounts of data.
        """
        # Build list of all apps to serialize
        from django.db.migrations.loader import MigrationLoader
        loader = MigrationLoader(self.connection)
        app_list = []
        for app_config in apps.get_app_configs():
            if (
                app_config.models_module is not None and
                app_config.label in loader.migrated_apps and
                app_config.name not in settings.TEST_NON_SERIALIZED_APPS
            ):
                app_list.append((app_config, None))

        # Make a function to iteratively return every object
        def get_objects():
            for model in serializers.sort_dependencies(app_list):
                if (model._meta.can_migrate(self.connection) and
                        router.allow_migrate_model(self.connection.alias, model)):
                    queryset = model._default_manager.using(self.connection.alias).order_by(model._meta.pk.name)
                    for obj in queryset.iterator():
                        yield obj
        # Serialize to a string
        out = StringIO()
        serializers.serialize("json", get_objects(), indent=None, stream=out)
        return out.getvalue() 
示例25
def serialize_db_to_string(self):
        """
        Serializes all data in the database into a JSON string.
        Designed only for test runner usage; will not handle large
        amounts of data.
        """
        # Build list of all apps to serialize
        from django.db.migrations.loader import MigrationLoader
        loader = MigrationLoader(self.connection)
        app_list = []
        for app_config in apps.get_app_configs():
            if (
                app_config.models_module is not None and
                app_config.label in loader.migrated_apps and
                app_config.name not in settings.TEST_NON_SERIALIZED_APPS
            ):
                app_list.append((app_config, None))

        # Make a function to iteratively return every object
        def get_objects():
            for model in serializers.sort_dependencies(app_list):
                if (model._meta.can_migrate(self.connection) and
                        router.allow_migrate_model(self.connection.alias, model)):
                    queryset = model._default_manager.using(self.connection.alias).order_by(model._meta.pk.name)
                    for obj in queryset.iterator():
                        yield obj
        # Serialize to a string
        out = StringIO()
        serializers.serialize("json", get_objects(), indent=None, stream=out)
        return out.getvalue() 
示例26
def make_migration(app_label="tests", from_state=None, to_state=None):
    """Generates migrations based on the specified app's state."""

    app_labels = [app_label]

    loader = MigrationLoader(None, ignore_no_migrations=True)
    loader.check_consistent_history(connection)

    questioner = NonInteractiveMigrationQuestioner(
        specified_apps=app_labels, dry_run=False
    )

    autodetector = MigrationAutodetector(
        from_state or loader.project_state(),
        to_state or ProjectState.from_apps(apps),
        questioner,
    )

    changes = autodetector.changes(
        graph=loader.graph,
        trim_to_apps=app_labels or None,
        convert_apps=app_labels or None,
        migration_name="test",
    )

    changes_for_app = changes.get(app_label)
    if not changes_for_app or len(changes_for_app) == 0:
        return None

    return changes_for_app[0] 
示例27
def __init__(
        self,
        path=None,
        ignore_name_contains=None,
        ignore_name=None,
        include_apps=None,
        exclude_apps=None,
        database=DEFAULT_DB_ALIAS,
        cache_path=DEFAULT_CACHE_PATH,
        no_cache=False,
        only_applied_migrations=False,
        only_unapplied_migrations=False,
        exclude_migration_tests=None,
        quiet=None,
        warnings_as_errors=False,
    ):
        # Store parameters and options
        self.django_path = path
        self.ignore_name_contains = ignore_name_contains
        self.ignore_name = ignore_name or tuple()
        self.include_apps = include_apps
        self.exclude_apps = exclude_apps
        self.exclude_migration_tests = exclude_migration_tests or []
        self.database = database or DEFAULT_DB_ALIAS
        self.cache_path = cache_path or DEFAULT_CACHE_PATH
        self.no_cache = no_cache
        self.only_applied_migrations = only_applied_migrations
        self.only_unapplied_migrations = only_unapplied_migrations
        self.quiet = quiet or []
        self.warnings_as_errors = warnings_as_errors

        # Initialise counters
        self.reset_counters()

        # Initialise cache. Read from old, write to new to prune old entries.
        if self.should_use_cache():
            self.old_cache = Cache(self.django_path, self.database, self.cache_path)
            self.new_cache = Cache(self.django_path, self.database, self.cache_path)
            self.old_cache.load()

        # Initialise migrations
        from django.db.migrations.loader import MigrationLoader

        self.migration_loader = MigrationLoader(
            connection=connections[self.database], load=True
        )