mirror of
https://github.com/django/django.git
synced 2026-02-09 02:49:25 +08:00
Fixed #36141 -- Checked for applied replaced migrations recursively.
Regression in 64b1ac7292.
This commit is contained in:
@@ -304,8 +304,7 @@ class MigrationExecutor:
|
||||
"""
|
||||
applied = self.recorder.applied_migrations()
|
||||
for key, migration in self.loader.replacements.items():
|
||||
all_applied = all(m in applied for m in migration.replaces)
|
||||
if all_applied and key not in applied:
|
||||
if key not in applied and self.loader.all_replaced_applied(key, applied):
|
||||
self.recorder.record_applied(*key)
|
||||
|
||||
def detect_soft_applied(self, project_state, migration):
|
||||
|
||||
@@ -356,11 +356,8 @@ class MigrationLoader:
|
||||
if parent not in applied:
|
||||
# Skip unapplied squashed migrations that have all of their
|
||||
# `replaces` applied.
|
||||
if parent in self.replacements:
|
||||
if all(
|
||||
m in applied for m in self.replacements[parent].replaces
|
||||
):
|
||||
continue
|
||||
if self.all_replaced_applied(parent.key, applied):
|
||||
continue
|
||||
raise InconsistentMigrationHistory(
|
||||
"Migration {}.{} is applied before its dependency "
|
||||
"{}.{} on database '{}'.".format(
|
||||
@@ -372,6 +369,20 @@ class MigrationLoader:
|
||||
)
|
||||
)
|
||||
|
||||
def all_replaced_applied(self, migration_key, applied):
|
||||
"""
|
||||
Checks (recursively) whether all replaced migrations are applied.
|
||||
"""
|
||||
if migration_key in self.replacements:
|
||||
for replaced_key in self.replacements[migration_key].replaces:
|
||||
if replaced_key not in applied and not self.all_replaced_applied(
|
||||
replaced_key, applied
|
||||
):
|
||||
return False
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def detect_conflicts(self):
|
||||
"""
|
||||
Look through the loaded graph and detect any conflicts - apps
|
||||
|
||||
@@ -3161,6 +3161,60 @@ class SquashMigrationsTests(MigrationTestBase):
|
||||
]
|
||||
self.assertNotIn("migrations", applied_app_labels)
|
||||
|
||||
def test_double_replaced_migrations_are_checked_correctly(self):
|
||||
"""
|
||||
If replaced migrations are already applied and replacing migrations
|
||||
are not, then migrate should not fail with
|
||||
InconsistentMigrationHistory.
|
||||
"""
|
||||
with self.temporary_migration_module():
|
||||
call_command(
|
||||
"makemigrations",
|
||||
"migrations",
|
||||
"--empty",
|
||||
interactive=False,
|
||||
verbosity=0,
|
||||
)
|
||||
call_command(
|
||||
"makemigrations",
|
||||
"migrations",
|
||||
"--empty",
|
||||
interactive=False,
|
||||
verbosity=0,
|
||||
)
|
||||
call_command(
|
||||
"makemigrations",
|
||||
"migrations",
|
||||
"--empty",
|
||||
interactive=False,
|
||||
verbosity=0,
|
||||
)
|
||||
call_command(
|
||||
"makemigrations",
|
||||
"migrations",
|
||||
"--empty",
|
||||
interactive=False,
|
||||
verbosity=0,
|
||||
)
|
||||
call_command("migrate", "migrations", interactive=False, verbosity=0)
|
||||
call_command(
|
||||
"squashmigrations",
|
||||
"migrations",
|
||||
"0001",
|
||||
"0002",
|
||||
interactive=False,
|
||||
verbosity=0,
|
||||
)
|
||||
call_command(
|
||||
"squashmigrations",
|
||||
"migrations",
|
||||
"0001_initial_squashed",
|
||||
"0003",
|
||||
interactive=False,
|
||||
verbosity=0,
|
||||
)
|
||||
call_command("migrate", "migrations", interactive=False, verbosity=0)
|
||||
|
||||
def test_squashmigrations_initial_attribute(self):
|
||||
with self.temporary_migration_module(
|
||||
module="migrations.test_migrations"
|
||||
|
||||
Reference in New Issue
Block a user