mirror of
https://github.com/django/django.git
synced 2024-12-01 15:42:04 +01:00
Fixed #22204: Bad circular-dep-breaking if more than one per run
This commit is contained in:
parent
8ce3ea687c
commit
e46e15e5a1
@ -94,9 +94,14 @@ class MigrationAutodetector(object):
|
||||
# Phase 2 is progressively adding pending models, splitting up into two
|
||||
# migrations if required.
|
||||
pending_new_fks = []
|
||||
added_phase_2 = set()
|
||||
while pending_add:
|
||||
# Is there one we can add that has all dependencies satisfied?
|
||||
satisfied = [(m, rf) for m, rf in pending_add.items() if all((al, mn) not in pending_add for f, al, mn in rf)]
|
||||
satisfied = [
|
||||
(m, rf)
|
||||
for m, rf in pending_add.items()
|
||||
if all((al, mn) not in pending_add for f, al, mn in rf)
|
||||
]
|
||||
if satisfied:
|
||||
(app_label, model_name), related_fields = sorted(satisfied)[0]
|
||||
model_state = self.to_state.models[app_label, model_name]
|
||||
@ -107,7 +112,10 @@ class MigrationAutodetector(object):
|
||||
fields=model_state.fields,
|
||||
options=model_state.options,
|
||||
bases=model_state.bases,
|
||||
)
|
||||
),
|
||||
# If it's already been added in phase 2 put it in a new
|
||||
# migration for safety.
|
||||
new=any((al, mn) in added_phase_2 for f, al, mn in related_fields),
|
||||
)
|
||||
for field_name, other_app_label, other_model_name in related_fields:
|
||||
# If it depends on a swappable something, add a dynamic depend'cy
|
||||
@ -117,6 +125,7 @@ class MigrationAutodetector(object):
|
||||
elif app_label != other_app_label:
|
||||
self.add_dependency(app_label, other_app_label)
|
||||
del pending_add[app_label, model_name]
|
||||
added_phase_2.add((app_label, model_name))
|
||||
# Ah well, we'll need to split one. Pick deterministically.
|
||||
else:
|
||||
(app_label, model_name), related_fields = sorted(pending_add.items())[0]
|
||||
@ -342,6 +351,7 @@ class MigrationAutodetector(object):
|
||||
else:
|
||||
new_name = "%04i_%s" % (next_number, self.suggest_name(migration.operations))
|
||||
name_map[(app_label, migration.name)] = (app_label, new_name)
|
||||
next_number += 1
|
||||
migration.name = new_name
|
||||
# Now fix dependencies
|
||||
for app_label, migrations in changes.items():
|
||||
|
@ -24,6 +24,7 @@ class AutodetectorTests(TestCase):
|
||||
author_proxy_notproxy = ModelState("testapp", "AuthorProxy", [], {}, ("testapp.author", ))
|
||||
publisher = ModelState("testapp", "Publisher", [("id", models.AutoField(primary_key=True)), ("name", models.CharField(max_length=100))])
|
||||
publisher_with_author = ModelState("testapp", "Publisher", [("id", models.AutoField(primary_key=True)), ("author", models.ForeignKey("testapp.Author")), ("name", models.CharField(max_length=100))])
|
||||
publisher_with_book = ModelState("testapp", "Publisher", [("id", models.AutoField(primary_key=True)), ("author", models.ForeignKey("otherapp.Book")), ("name", models.CharField(max_length=100))])
|
||||
other_pony = ModelState("otherapp", "Pony", [("id", models.AutoField(primary_key=True))])
|
||||
other_stable = ModelState("otherapp", "Stable", [("id", models.AutoField(primary_key=True))])
|
||||
third_thing = ModelState("thirdapp", "Thing", [("id", models.AutoField(primary_key=True))])
|
||||
@ -243,7 +244,7 @@ class AutodetectorTests(TestCase):
|
||||
"""
|
||||
# Make state
|
||||
before = self.make_project_state([])
|
||||
after = self.make_project_state([self.author_with_book, self.book])
|
||||
after = self.make_project_state([self.author_with_book, self.book, self.publisher_with_book])
|
||||
autodetector = MigrationAutodetector(before, after)
|
||||
changes = autodetector._detect_changes()
|
||||
# Right number of migrations?
|
||||
@ -251,7 +252,7 @@ class AutodetectorTests(TestCase):
|
||||
self.assertEqual(len(changes['otherapp']), 2)
|
||||
# Right number of actions?
|
||||
migration1 = changes['testapp'][0]
|
||||
self.assertEqual(len(migration1.operations), 1)
|
||||
self.assertEqual(len(migration1.operations), 2)
|
||||
migration2 = changes['otherapp'][0]
|
||||
self.assertEqual(len(migration2.operations), 1)
|
||||
migration3 = changes['otherapp'][1]
|
||||
|
Loading…
Reference in New Issue
Block a user