Fixed #24129 -- Added indicator that migrations are rendering the initial state

Thanks Tim Graham for the review.
This commit is contained in:
Markus Holtermann 2015-01-11 21:07:45 +01:00
parent 9f51d0c86d
commit eeb88123e7
3 changed files with 59 additions and 2 deletions

View File

@ -216,7 +216,7 @@ 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, fake=False):
def migration_progress_callback(self, action, migration=None, fake=False):
if self.verbosity >= 1:
compute_time = self.verbosity > 1
if action == "apply_start":
@ -241,6 +241,14 @@ class Command(BaseCommand):
self.stdout.write(self.style.MIGRATE_SUCCESS(" FAKED" + elapsed))
else:
self.stdout.write(self.style.MIGRATE_SUCCESS(" OK" + elapsed))
elif action == "render_start":
if compute_time:
self.start = time.time()
self.stdout.write(" Rendering model states...", ending="")
self.stdout.flush()
elif action == "render_success":
elapsed = " (%.3fs)" % (time.time() - self.start) if compute_time else ""
self.stdout.write(self.style.MIGRATE_SUCCESS(" DONE" + elapsed))
def sync_apps(self, connection, app_labels):
"Runs the old syncdb-style operation on a list of app_labels."

View File

@ -77,7 +77,11 @@ class MigrationExecutor(object):
# if the migration is being run.
states = {}
state = ProjectState(real_apps=list(self.loader.unmigrated_apps))
if self.progress_callback:
self.progress_callback("render_start")
state.apps # Render all real_apps -- performance critical
if self.progress_callback:
self.progress_callback("render_success")
# Phase 1 -- Store all required states
for migration, _ in full_plan:
if migration in migrations_to_run:

View File

@ -150,7 +150,7 @@ class ExecutorTests(MigrationTestBase):
"""
state = {"faked": None}
def fake_storer(phase, migration, fake):
def fake_storer(phase, migration=None, fake=None):
state["faked"] = fake
executor = MigrationExecutor(connection, progress_callback=fake_storer)
# Were the tables there before?
@ -323,6 +323,51 @@ class ExecutorTests(MigrationTestBase):
self.assertTableNotExists("lookuperror_b_b1")
self.assertTableNotExists("lookuperror_c_c1")
@override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations"})
def test_process_callback(self):
"""
#24129 - Tests callback process
"""
call_args_list = []
def callback(*args):
call_args_list.append(args)
executor = MigrationExecutor(connection, progress_callback=callback)
# Were the tables there before?
self.assertTableNotExists("migrations_author")
self.assertTableNotExists("migrations_tribble")
executor.migrate([
("migrations", "0001_initial"),
("migrations", "0002_second"),
])
# Rebuild the graph to reflect the new DB state
executor.loader.build_graph()
executor.migrate([
("migrations", None),
("migrations", None),
])
self.assertTableNotExists("migrations_author")
self.assertTableNotExists("migrations_tribble")
migrations = executor.loader.graph.nodes
expected = [
("render_start", ),
("render_success", ),
("apply_start", migrations['migrations', '0001_initial'], False),
("apply_success", migrations['migrations', '0001_initial'], False),
("apply_start", migrations['migrations', '0002_second'], False),
("apply_success", migrations['migrations', '0002_second'], False),
("render_start", ),
("render_success", ),
("unapply_start", migrations['migrations', '0002_second'], False),
("unapply_success", migrations['migrations', '0002_second'], False),
("unapply_start", migrations['migrations', '0001_initial'], False),
("unapply_success", migrations['migrations', '0001_initial'], False),
]
self.assertEqual(call_args_list, expected)
class FakeLoader(object):
def __init__(self, graph, applied):