mirror of
https://github.com/django/django.git
synced 2025-10-31 09:41:08 +00:00
Auto-apply initial migrations if their tables exist already.
This commit is contained in:
@@ -127,18 +127,24 @@ class Command(BaseCommand):
|
||||
# to do at this point.
|
||||
emit_post_migrate_signal(created_models, self.verbosity, self.interactive, connection.alias)
|
||||
|
||||
def migration_progress_callback(self, action, migration):
|
||||
def migration_progress_callback(self, action, migration, fake=False):
|
||||
if self.verbosity >= 1:
|
||||
if action == "apply_start":
|
||||
self.stdout.write(" Applying %s..." % migration, ending="")
|
||||
self.stdout.flush()
|
||||
elif action == "apply_success":
|
||||
self.stdout.write(self.style.MIGRATE_SUCCESS(" OK"))
|
||||
if fake:
|
||||
self.stdout.write(self.style.MIGRATE_SUCCESS(" FAKED"))
|
||||
else:
|
||||
self.stdout.write(self.style.MIGRATE_SUCCESS(" OK"))
|
||||
elif action == "unapply_start":
|
||||
self.stdout.write(" Unapplying %s..." % migration, ending="")
|
||||
self.stdout.flush()
|
||||
elif action == "unapply_success":
|
||||
self.stdout.write(self.style.MIGRATE_SUCCESS(" OK"))
|
||||
if fake:
|
||||
self.stdout.write(self.style.MIGRATE_SUCCESS(" FAKED"))
|
||||
else:
|
||||
self.stdout.write(self.style.MIGRATE_SUCCESS(" OK"))
|
||||
|
||||
def sync_apps(self, connection, apps):
|
||||
"Runs the old syncdb-style operation on a list of apps."
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from django.db import migrations
|
||||
from .loader import MigrationLoader
|
||||
from .recorder import MigrationRecorder
|
||||
|
||||
@@ -81,27 +82,32 @@ class MigrationExecutor(object):
|
||||
Runs a migration forwards.
|
||||
"""
|
||||
if self.progress_callback:
|
||||
self.progress_callback("apply_start", migration)
|
||||
self.progress_callback("apply_start", migration, fake)
|
||||
if not fake:
|
||||
with self.connection.schema_editor() as schema_editor:
|
||||
project_state = self.loader.graph.project_state((migration.app_label, migration.name), at_end=False)
|
||||
migration.apply(project_state, schema_editor)
|
||||
# Test to see if this is an already-applied initial migration
|
||||
if not migration.dependencies and self.detect_soft_applied(migration):
|
||||
fake = True
|
||||
else:
|
||||
# Alright, do it normally
|
||||
with self.connection.schema_editor() as schema_editor:
|
||||
project_state = self.loader.graph.project_state((migration.app_label, migration.name), at_end=False)
|
||||
migration.apply(project_state, schema_editor)
|
||||
# For replacement migrations, record individual statuses
|
||||
if migration.replaces:
|
||||
for app_label, name in migration.replaces:
|
||||
self.recorder.record_applied(app_label, name)
|
||||
else:
|
||||
self.recorder.record_applied(migration.app_label, migration.name)
|
||||
# Report prgress
|
||||
# Report progress
|
||||
if self.progress_callback:
|
||||
self.progress_callback("apply_success", migration)
|
||||
self.progress_callback("apply_success", migration, fake)
|
||||
|
||||
def unapply_migration(self, migration, fake=False):
|
||||
"""
|
||||
Runs a migration backwards.
|
||||
"""
|
||||
if self.progress_callback:
|
||||
self.progress_callback("unapply_start", migration)
|
||||
self.progress_callback("unapply_start", migration, fake)
|
||||
if not fake:
|
||||
with self.connection.schema_editor() as schema_editor:
|
||||
project_state = self.loader.graph.project_state((migration.app_label, migration.name), at_end=False)
|
||||
@@ -114,4 +120,19 @@ class MigrationExecutor(object):
|
||||
self.recorder.record_unapplied(migration.app_label, migration.name)
|
||||
# Report progress
|
||||
if self.progress_callback:
|
||||
self.progress_callback("unapply_success", migration)
|
||||
self.progress_callback("unapply_success", migration, fake)
|
||||
|
||||
def detect_soft_applied(self, migration):
|
||||
"""
|
||||
Tests whether a migration has been implicity applied - that the
|
||||
tables it would create exist. This is intended only for use
|
||||
on initial migrations (as it only looks for CreateModel).
|
||||
"""
|
||||
project_state = self.loader.graph.project_state((migration.app_label, migration.name), at_end=True)
|
||||
app_cache = project_state.render()
|
||||
for operation in migration.operations:
|
||||
if isinstance(operation, migrations.CreateModel):
|
||||
model = app_cache.get_model(migration.app_label, operation.name)
|
||||
if model._meta.db_table not in self.connection.introspection.get_table_list(self.connection.cursor()):
|
||||
return False
|
||||
return True
|
||||
|
||||
Reference in New Issue
Block a user