#36184: Migrating forward to a replaced migration fails
---------------------------------------+----------------------------------
Reporter: Jacob Walls | Owner: Jacob Walls
Type: Bug | Status: assigned
Component: Migrations | Version: dev
Severity: Normal | Keywords: squashed, squash
Triage Stage: Unreviewed | Has patch: 0
Needs documentation: 0 | Needs tests: 0
Patch needs improvement: 0 | Easy pickings: 0
UI/UX: 0 |
---------------------------------------+----------------------------------
You can migrate backward to a replaced migration since #24900, but
apparently not forward. The fix looks to be trivial.
Failing test:
{{{#!diff
diff --git a/tests/migrations/test_commands.py
b/tests/migrations/test_commands.py
index 5ff5cd4b26..39fdbf1278 100644
--- a/tests/migrations/test_commands.py
+++ b/tests/migrations/test_commands.py
@@ -1325,6 +1325,16 @@ class MigrateTests(MigrationTestBase):
# Unmigrate everything.
call_command("migrate", "migrations", "zero",
verbosity=0)
+ @override_settings(
+ MIGRATION_MODULES={"migrations":
"migrations.test_migrations_squashed"}
+ )
+ def test_migrate_forward_to_squashed_migration(self):
+ try:
+ call_command("migrate", "migrations", "0001_initial",
verbosity=0)
+ finally:
+ # Unmigrate everything.
+ call_command("migrate", "migrations", "zero", verbosity=0)
+
@override_settings(
}}}
----
{{{#!py
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.
{{{#!py
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))
}}}
--
Ticket URL: <
https://code.djangoproject.com/ticket/36184>
Django <
https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.