summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Meyer <carl@oddbird.net>2015-06-03 13:46:01 -0600
committerCarl Meyer <carl@oddbird.net>2015-06-03 15:48:53 -0600
commitfeed5ad2a07223d14f8304920fa761c972559b07 (patch)
treed2704a8caa83e10f656e113c5c53a142bd42719c
parentf082813d67e6482b6ab8fbf4f7550de278e42d7f (diff)
[1.8.x] Refs #24628 -- Added a second test and a docstring comment to avoid regression.
Backport of 5c085ea7b3f3ff10389aeed327e018581791876a from master.
-rw-r--r--django/db/migrations/executor.py8
-rw-r--r--tests/migrations/test_executor.py24
2 files changed, 32 insertions, 0 deletions
diff --git a/django/db/migrations/executor.py b/django/db/migrations/executor.py
index af2207c9ab..39ed2e4d3d 100644
--- a/django/db/migrations/executor.py
+++ b/django/db/migrations/executor.py
@@ -180,6 +180,14 @@ class MigrationExecutor(object):
def check_replacements(self):
"""
Mark replacement migrations applied if their replaced set all are.
+
+ We do this unconditionally on every migrate, rather than just when
+ migrations are applied or unapplied, so as to correctly handle the case
+ when a new squash migration is pushed to a deployment that already had
+ all its replaced migrations applied. In this case no new migration will
+ be applied, but we still want to correctly maintain the applied state
+ of the squash migration.
+
"""
applied = self.recorder.applied_migrations()
for key, migration in self.loader.replacements.items():
diff --git a/tests/migrations/test_executor.py b/tests/migrations/test_executor.py
index 9946dd4503..0eefc32b1f 100644
--- a/tests/migrations/test_executor.py
+++ b/tests/migrations/test_executor.py
@@ -437,6 +437,30 @@ class ExecutorTests(MigrationTestBase):
recorder.applied_migrations(),
)
+ @override_settings(MIGRATION_MODULES={"migrations": "migrations.test_migrations_squashed"})
+ def test_migrate_marks_replacement_applied_even_if_it_did_nothing(self):
+ """
+ A new squash migration will be marked as applied even if all its
+ replaced migrations were previously already applied.
+
+ Ticket #24628.
+
+ """
+ recorder = MigrationRecorder(connection)
+ # Record all replaced migrations as applied
+ recorder.record_applied("migrations", "0001_initial")
+ recorder.record_applied("migrations", "0002_second")
+ executor = MigrationExecutor(connection)
+ executor.migrate([("migrations", "0001_squashed_0002")])
+
+ # Because 0001 and 0002 are both applied, even though this migrate run
+ # didn't apply anything new, their squashed replacement should be
+ # marked as applied.
+ self.assertIn(
+ ("migrations", "0001_squashed_0002"),
+ recorder.applied_migrations(),
+ )
+
class FakeLoader(object):
def __init__(self, graph, applied):