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)
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()
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
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)
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 )