Fixed #27845 -- Allowed both right and left optimizations of operations.
Thanks Raphael Gaschignard for the suggestion.
This commit is contained in:
parent
0025dd5eb4
commit
37cafbfb79
|
@ -42,21 +42,29 @@ class MigrationOptimizer:
|
|||
"""Inner optimization loop."""
|
||||
new_operations = []
|
||||
for i, operation in enumerate(operations):
|
||||
right = True # Should we reduce on the right or on the left.
|
||||
# Compare it to each operation after it
|
||||
for j, other in enumerate(operations[i + 1:]):
|
||||
in_between = operations[i + 1:i + j + 1]
|
||||
result = operation.reduce(other, in_between, app_label)
|
||||
if isinstance(result, list):
|
||||
# Add operations optimized through, optimized operations,
|
||||
# and the remaining ones.
|
||||
new_operations.extend(in_between)
|
||||
new_operations.extend(result)
|
||||
if right:
|
||||
new_operations.extend(in_between)
|
||||
new_operations.extend(result)
|
||||
elif all(op.reduce(other, [], app_label) is True for op in in_between):
|
||||
# Perform a left reduction if all of the in-between
|
||||
# operations can optimize through other.
|
||||
new_operations.extend(result)
|
||||
new_operations.extend(in_between)
|
||||
else:
|
||||
# Otherwise keep trying.
|
||||
new_operations.append(operation)
|
||||
break
|
||||
new_operations.extend(operations[i + j + 2:])
|
||||
return new_operations
|
||||
if not result:
|
||||
# We can't optimize across `other`.
|
||||
new_operations.append(operation)
|
||||
break
|
||||
elif not result:
|
||||
# Can't perform a right reduction.
|
||||
right = False
|
||||
else:
|
||||
new_operations.append(operation)
|
||||
return new_operations
|
||||
|
|
|
@ -270,8 +270,6 @@ class OptimizerTests(SimpleTestCase):
|
|||
app_label="testapp",
|
||||
)
|
||||
|
||||
# This could be optimized a bit more but it generates a valid set of
|
||||
# operations.
|
||||
self.assertOptimizesTo(
|
||||
[
|
||||
migrations.CreateModel('Book', [('name', models.CharField(max_length=255))]),
|
||||
|
@ -284,18 +282,12 @@ class OptimizerTests(SimpleTestCase):
|
|||
migrations.DeleteModel('Person'),
|
||||
],
|
||||
[
|
||||
migrations.CreateModel('Person', [('name', models.CharField(max_length=255))]),
|
||||
migrations.CreateModel('Book', [
|
||||
('name', models.CharField(max_length=255)),
|
||||
('author', models.ForeignKey('test_app.Person', models.CASCADE)),
|
||||
]),
|
||||
migrations.CreateModel('Book', [('name', models.CharField(max_length=255))]),
|
||||
migrations.CreateModel('Reviewer', [('name', models.CharField(max_length=255))]),
|
||||
migrations.CreateModel('Review', [
|
||||
('book', models.ForeignKey('test_app.Book', models.CASCADE)),
|
||||
('reviewer', models.ForeignKey('test_app.Reviewer', models.CASCADE)),
|
||||
]),
|
||||
migrations.RemoveField('book', 'author'),
|
||||
migrations.DeleteModel('Person'),
|
||||
],
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in New Issue