예제 #1
0
def _migrate_from_south(verbosity):
    from django.db.migrations.recorder import MigrationRecorder

    connection = connections["default"]

    if not _has_south_history(connection):
        return

    # ensure the django_migrations relation exists
    recorder = MigrationRecorder(connection)
    recorder.ensure_schema()

    for django_app_name, django_migration in DJANGO_MIGRATIONS:
        _fake_django_migration(connection, django_app_name, django_migration, verbosity)

    for (
        south_app_name,
        south_migration,
        django_app_name,
        django_migration,
        south_migration_required,
        south_migration_required_error,
    ) in settings.SOUTH_MIGRATION_CONVERSIONS:
        if _has_applied_south_migration(connection, south_app_name, south_migration):
            _fake_django_migration(connection, django_app_name, django_migration)
        elif south_migration_required:
            raise Exception(south_migration_required_error)
예제 #2
0
def unrecord_applied_migrations(connection, app_label, migration_names=None):
    """Remove the recordings of applied migrations from the database.

    This can only be called when on Django 1.7 or higher.

    Args:
        connection (django.db.backends.base.BaseDatabaseWrapper):
            The connection used to unrecord applied migrations.

        app_label (unicode):
            The app label that the migrations pertain to.

        migration_names (list of unicode, optional):
            The list of migration names to unrecord. If not provided, all
            migrations for the app will be unrecorded.
    """
    assert supports_migrations, \
        'This cannot be called on Django 1.6 or earlier.'

    recorder = MigrationRecorder(connection)
    recorder.ensure_schema()

    queryset = recorder.migration_qs.filter(app=app_label)

    if migration_names:
        queryset = queryset.filter(name__in=migration_names)

    queryset.delete()
예제 #3
0
    def from_database(cls, connection, app_label=None):
        """Create a MigrationList based on recorded migrations.

        Args:
            connection (django.db.backends.base.BaseDatabaseWrapper):
                The database connection used to query for migrations.

            app_label (unicode, optional):
                An app label to filter migrations by.

        Returns:
            MigrationList:
            The new migration list.
        """
        recorder = MigrationRecorder(connection)
        recorder.ensure_schema()

        migration_list = cls()
        queryset = recorder.migration_qs

        if app_label:
            queryset = queryset.filter(app=app_label)

        for recorded_migration in queryset.all():
            migration_list.add_recorded_migration(recorded_migration)

        return migration_list
예제 #4
0
def run_migrations(args, options, executor_codename, schema_name, tenant_type='',
                   allow_atomic=True, idx=None, count=None):
    from django.core.management import color
    from django.core.management.base import OutputWrapper
    from django.db import connections
    style = color.color_style()

    def style_func(msg):
        percent_str = ''
        if idx is not None and count is not None and count > 0:
            percent_str = '%d/%d (%s%%) ' % (idx + 1, count, int(100 * (idx + 1) / count))

        message = '[%s%s:%s] %s' % (
            percent_str,
            style.NOTICE(executor_codename),
            style.NOTICE(schema_name),
            msg
        )
        signal_message = '[%s%s:%s] %s' % (
            percent_str,
            executor_codename,
            schema_name,
            msg
        )
        schema_migrate_message.send(run_migrations, message=signal_message)
        return message

    connection = connections[options.get('database', get_tenant_database_alias())]
    connection.set_schema(schema_name, tenant_type=tenant_type)

    # ensure that django_migrations table is created in the schema before migrations run, otherwise the migration
    # table in the public schema gets picked and no migrations are applied
    migration_recorder = MigrationRecorder(connection)
    migration_recorder.ensure_schema()

    stdout = OutputWrapper(sys.stdout)
    stdout.style_func = style_func
    stderr = OutputWrapper(sys.stderr)
    stderr.style_func = style_func
    if int(options.get('verbosity', 1)) >= 1:
        stdout.write(style.NOTICE("=== Starting migration"))
    MigrateCommand(stdout=stdout, stderr=stderr).execute(*args, **options)

    try:
        transaction.commit()
        connection.close()
        connection.connection = None
    except transaction.TransactionManagementError:
        if not allow_atomic:
            raise

        # We are in atomic transaction, don't close connections
        pass

    connection.set_schema_to_public()
    schema_migrated.send(run_migrations, schema_name=schema_name)
예제 #5
0
def record_applied_migrations(connection, migrations):
    """Record a list of applied migrations to the database.

    This can only be called when on Django 1.7 or higher.

    Args:
        connection (django.db.backends.base.BaseDatabaseWrapper):
            The connection used to record applied migrations.

        migrations (MigrationList):
            The list of migration targets to record as applied.
    """
    assert supports_migrations, \
        'This cannot be called on Django 1.6 or earlier.'

    recorder = MigrationRecorder(connection)
    recorder.ensure_schema()

    recorder.migration_qs.bulk_create(
        recorder.Migration(app=info['app_label'],
                           name=info['name'])
        for info in migrations
    )