Opened 3 hours ago

Last modified 2 hours ago

#36184 assigned Bug

Migrating forward to a replaced migration fails

Reported by: Jacob Walls Owned by: Jacob Walls
Component: Migrations Version: dev
Severity: Normal Keywords: squashed, squash
Cc: Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

You can migrate backward to a replaced migration since #24900, but apparently not forward. The fix looks to be trivial.

Failing test:

  • tests/migrations/test_commands.py

    diff --git a/tests/migrations/test_commands.py b/tests/migrations/test_commands.py
    index 5ff5cd4b26..39fdbf1278 100644
    a b class MigrateTests(MigrationTestBase):  
    13251325                # Unmigrate everything.
    13261326                call_command("migrate", "migrations", "zero", verbosity=0)
    13271327
     1328    @override_settings(
     1329        MIGRATION_MODULES={"migrations": "migrations.test_migrations_squashed"}
     1330    )
     1331    def test_migrate_forward_to_squashed_migration(self):
     1332        try:
     1333            call_command("migrate", "migrations", "0001_initial", verbosity=0)
     1334        finally:
     1335            # Unmigrate everything.
     1336            call_command("migrate", "migrations", "zero", verbosity=0)
     1337
    13281338    @override_settings(

  File "/Users/.../django/django/db/migrations/executor.py", line 67, in migration_plan
    for migration in self.loader.graph.forwards_plan(target):
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/.../django/django/db/migrations/graph.py", line 207, in forwards_plan
    raise NodeNotFoundError("Node %r not a valid node" % (target,), target)
django.db.migrations.exceptions.NodeNotFoundError: Node ('migrations', '0001_initial') not a valid node

Rough patch -- this is just a copy/paste of a block above, so an intelligent refactor would be the only interesting part.

diff --git a/django/db/migrations/executor.py b/django/db/migrations/executor.py
index 13afa5988f..f57bc2b090 100644
--- a/django/db/migrations/executor.py
+++ b/django/db/migrations/executor.py
@@ -64,6 +64,15 @@ class MigrationExecutor:
                             plan.append((self.loader.graph.nodes[migration], True))
                             applied.pop(migration)
             else:
+                # If the target is missing, it's likely a replaced migration.
+                # Reload the graph without replacements.
+                if (
+                    self.loader.replace_migrations
+                    and target not in self.loader.graph.node_map
+                ):
+                    self.loader.replace_migrations = False
+                    self.loader.build_graph()
+                    return self.migration_plan(targets, clean_start=clean_start)
                 for migration in self.loader.graph.forwards_plan(target):
                     if migration not in applied:
                         plan.append((self.loader.graph.nodes[migration], False))

Change History (1)

comment:1 by Sarah Boyce, 2 hours ago

Triage Stage: UnreviewedAccepted
Note: See TracTickets for help on using tickets.
Back to Top