diff options
| author | Carl Meyer <carl@oddbird.net> | 2015-06-03 13:46:01 -0600 |
|---|---|---|
| committer | Carl Meyer <carl@oddbird.net> | 2015-06-03 15:48:53 -0600 |
| commit | feed5ad2a07223d14f8304920fa761c972559b07 (patch) | |
| tree | d2704a8caa83e10f656e113c5c53a142bd42719c | |
| parent | f082813d67e6482b6ab8fbf4f7550de278e42d7f (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.py | 8 | ||||
| -rw-r--r-- | tests/migrations/test_executor.py | 24 |
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): |
