Commit eeb88123 authored by Markus Holtermann's avatar Markus Holtermann
Browse files

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

Thanks Tim Graham for the review.
parent 9f51d0c8
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -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."
+4 −0
Original line number Diff line number Diff line
@@ -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:
+46 −1
Original line number Diff line number Diff line
@@ -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):