コード例 #1
0
ファイル: test_executor.py プロジェクト: stjordanis/django
    def test_migrations_not_applied_on_deferred_sql_failure(self):
        """Migrations are not recorded if deferred SQL application fails."""
        class DeferredSQL:
            def __str__(self):
                raise DatabaseError('Failed to apply deferred SQL')

        class Migration(migrations.Migration):
            atomic = False

            def apply(self, project_state, schema_editor, collect_sql=False):
                schema_editor.deferred_sql.append(DeferredSQL())

        executor = MigrationExecutor(connection)
        with self.assertRaisesMessage(DatabaseError,
                                      'Failed to apply deferred SQL'):
            executor.apply_migration(
                ProjectState(),
                Migration('0001_initial', 'deferred_sql'),
            )
        # The migration isn't recorded as applied since it failed.
        migration_recorder = MigrationRecorder(connection)
        self.assertIs(
            migration_recorder.migration_qs.filter(
                app='deferred_sql',
                name='0001_initial',
            ).exists(),
            False,
        )
コード例 #2
0
def execute_migration(schema_editor, operations, project=None):
    """Executes the specified migration operations
    using the specified schema editor.

    Arguments:
        schema_editor:
            The schema editor to use to
            execute the migrations.

        operations:
            The migration operations to execute.

        project:
            The project state to use during the
            migrations.
    """

    project = project or migrations.state.ProjectState.from_apps(apps)

    class Migration(migrations.Migration):
        pass

    Migration.operations = operations

    executor = MigrationExecutor(schema_editor.connection)
    executor.apply_migration(project, Migration('eh', 'postgres_extra'))
コード例 #3
0
def apply_migration(operations, state=None, backwards: bool = False):
    """Executes the specified migration operations using the specified schema
    editor.

    Arguments:
        operations:
            The migration operations to execute.

        state:
            The state state to use during the
            migrations.

        backwards:
            Whether to apply the operations
            in reverse (backwards).
    """

    state = state or migrations.state.ProjectState.from_apps(apps)

    class Migration(migrations.Migration):
        pass

    Migration.operations = operations

    migration = Migration("migration", "tests")
    executor = MigrationExecutor(connection)

    if not backwards:
        executor.apply_migration(state, migration)
    else:
        executor.unapply_migration(state, migration)

    return migration
コード例 #4
0
ファイル: test_executor.py プロジェクト: thibaudcolas/django
    def test_migrations_applied_and_recorded_atomically(self):
        """Migrations are applied and recorded atomically."""
        class Migration(migrations.Migration):
            operations = [
                migrations.CreateModel(
                    "model",
                    [
                        ("id", models.AutoField(primary_key=True)),
                    ],
                ),
            ]

        executor = MigrationExecutor(connection)
        with mock.patch(
                "django.db.migrations.executor.MigrationExecutor.record_migration"
        ) as record_migration:
            record_migration.side_effect = RuntimeError(
                "Recording migration failed.")
            with self.assertRaisesMessage(RuntimeError,
                                          "Recording migration failed."):
                executor.apply_migration(
                    ProjectState(),
                    Migration("0001_initial", "record_migration"),
                )
                executor.migrate([("migrations", "0001_initial")])
        # The migration isn't recorded as applied since it failed.
        migration_recorder = MigrationRecorder(connection)
        self.assertIs(
            migration_recorder.migration_qs.filter(
                app="record_migration",
                name="0001_initial",
            ).exists(),
            False,
        )
        self.assertTableNotExists("record_migration_model")
コード例 #5
0
ファイル: test_executor.py プロジェクト: stjordanis/django
    def test_migrations_applied_and_recorded_atomically(self):
        """Migrations are applied and recorded atomically."""
        class Migration(migrations.Migration):
            operations = [
                migrations.CreateModel('model', [
                    ('id', models.AutoField(primary_key=True)),
                ]),
            ]

        executor = MigrationExecutor(connection)
        with mock.patch(
                'django.db.migrations.executor.MigrationExecutor.record_migration'
        ) as record_migration:
            record_migration.side_effect = RuntimeError(
                'Recording migration failed.')
            with self.assertRaisesMessage(RuntimeError,
                                          'Recording migration failed.'):
                executor.apply_migration(
                    ProjectState(),
                    Migration('0001_initial', 'record_migration'),
                )
                executor.migrate([('migrations', '0001_initial')])
        # The migration isn't recorded as applied since it failed.
        migration_recorder = MigrationRecorder(connection)
        self.assertIs(
            migration_recorder.migration_qs.filter(
                app='record_migration',
                name='0001_initial',
            ).exists(),
            False,
        )
        self.assertTableNotExists('record_migration_model')
コード例 #6
0
def on_pre_migrate(connection, **kwargs):
    """ Ensures that custom user migration executed before main migration
    process.

    The main problem with existing application custom user implementation is
    failing migration consistency check.
    But in fact migration is ok, the problem is that migration plan
    expects user migration applied before others.
    So only thing we need to do, is to force custom user migration.
    Here is approach when we detect such situation during migration process
    and manually applying custom user migration before checks executed.

    1. This method detects:
        1.1. if it executed within migrate command
        1.2. if other miggrations already applied
        1.3. custom_user migrations not applied
    2. Manually applies custom_user migration.

    """

    if len(argv) < 2 or argv[1] != 'migrate':
        return

    executor = MigrationExecutor(connection, get_migration_callback())
    executor.loader.load_disk()

    is_fresh = not executor.loader.applied_migrations
    is_applied = CUSTOM_USER_MIGRATION in executor.loader.applied_migrations
    if is_fresh or is_applied:
        return

    migration = executor.loader.disk_migrations[CUSTOM_USER_MIGRATION]
    state = executor._create_project_state(
        with_applied_migrations=True)  # noqa protected-access
    executor.apply_migration(state, migration)
コード例 #7
0
def get_fake_model():
    """Creates a fake model to use during unit tests."""

    global MODEL

    if MODEL:
        return MODEL

    class TestModel(LocalizedModel):
        """Model used for testing the :see:LocalizedAutoSlugField."""

        app_label = 'localized_fields'

        title = LocalizedField()
        slug = LocalizedAutoSlugField(populate_from='title')

    class TestProject:
        def clone(self, *args, **kwargs):
            return self

    class TestMigration(migrations.Migration):
        operations = [HStoreExtension()]

    with connection.schema_editor() as schema_editor:
        migration_executor = MigrationExecutor(schema_editor.connection)
        migration_executor.apply_migration(
            TestProject(), TestMigration('eh', 'localized_fields'))

        schema_editor.create_model(TestModel)

    MODEL = TestModel
    return MODEL
コード例 #8
0
def get_fake_model(fields=None, model_base=LocalizedModel, meta_options={}):
    """Creates a fake model to use during unit tests."""

    model = define_fake_model(fields, model_base, meta_options)

    class TestProject:

        def clone(self, *_args, **_kwargs):
            return self

        @property
        def apps(self):
            return self

    class TestMigration(migrations.Migration):
        operations = [HStoreExtension()]

    with connection.schema_editor() as schema_editor:
        migration_executor = MigrationExecutor(schema_editor.connection)
        migration_executor.apply_migration(
            TestProject(), TestMigration('eh', 'postgres_extra'))

        schema_editor.create_model(model)

    return model
コード例 #9
0
    def migrate(self):
        """Executes the recorded migrations."""

        while len(self.migrations) > 0:
            migration = self.migrations.pop()

            with connection.schema_editor() as schema_editor:
                migration_executor = MigrationExecutor(
                    schema_editor.connection)
                migration_executor.apply_migration(self.project_state,
                                                   migration)
コード例 #10
0
def apply_django_migration(migration_cls, migration_name='9999',
                           app_label='testapp', executor=None):
    if executor is None:
        executor = MigrationExecutor(connections[DEFAULT_DB_ALIAS])
    migration = migration_cls(migration_name, app_label)
    key = (migration.app_label, migration.name)

    executor.loader.graph.add_node(key, migration)
    for parent in migration.dependencies:
        executor.loader.graph.add_dependency(migration, key, parent)

    try:
        executor.apply_migration(migration)
    except TypeError:
        state = executor.loader.project_state(parent)
        executor.apply_migration(state, migration)
    return executor
コード例 #11
0
def get_fake_model(fields={}, model_base=models.Model, options={}):
    """Create fake model to use during unit tests."""

    model = define_fake_model(fields, model_base, options)

    class TestProject:
        def clone(self, *_args, **_kwargs):
            return self

    class TestMigration(migrations.Migration):
        operations = [HStoreExtension()]

    with connection.schema_editor() as schema_editor:
        migration_executor = MigrationExecutor(schema_editor.connection)
        migration_executor.apply_migration(
            TestProject(), TestMigration("caluma_extra", "core"))

        schema_editor.create_model(model)

    return model
コード例 #12
0
    def migrate(self, *filters: List[str]):
        """
        Executes the recorded migrations.

        Arguments:
            filters: List of strings to filter SQL statements on.

        Returns:
            The filtered calls of every migration
        """

        calls_for_migrations = []
        while len(self.migrations) > 0:
            migration = self.migrations.pop()

            with filtered_schema_editor(*filters) as (schema_editor, calls):
                migration_executor = MigrationExecutor(schema_editor.connection)
                migration_executor.apply_migration(
                    self.project_state, migration
                )
                calls_for_migrations.append(calls)

        return calls_for_migrations
コード例 #13
0
def get_fake_model(name='TestModel', fields=None):
    """Creates a fake model to use during unit tests."""

    model = define_fake_model(name, fields)

    class TestProject:
        def clone(self, *_args, **_kwargs):
            return self

        @property
        def apps(self):
            return self

    class TestMigration(migrations.Migration):
        operations = [HStoreExtension()]

    with connection.schema_editor() as schema_editor:
        migration_executor = MigrationExecutor(schema_editor.connection)
        migration_executor.apply_migration(
            TestProject(), TestMigration('eh', 'localized_fields'))

        schema_editor.create_model(model)

    return model