summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Charette <charette.s@gmail.com>2017-02-18 00:55:13 -0500
committerTim Graham <timograham@gmail.com>2018-07-11 10:49:50 -0400
commit37cafbfb791b2295b8c36cdabbdef0e5d951a64e (patch)
tree7721dd68e9f5cfcf1c2c19af1a0e041f9879884c
parent0025dd5eb42834af3c6566d5ef1dd1032a49f6c8 (diff)
Fixed #27845 -- Allowed both right and left optimizations of operations.
Thanks Raphael Gaschignard for the suggestion.
-rw-r--r--django/db/migrations/optimizer.py24
-rw-r--r--tests/migrations/test_optimizer.py10
2 files changed, 17 insertions, 17 deletions
diff --git a/django/db/migrations/optimizer.py b/django/db/migrations/optimizer.py
index 26ac88a221..7974dba66b 100644
--- a/django/db/migrations/optimizer.py
+++ b/django/db/migrations/optimizer.py
@@ -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
diff --git a/tests/migrations/test_optimizer.py b/tests/migrations/test_optimizer.py
index 973be67c80..a408db9ef2 100644
--- a/tests/migrations/test_optimizer.py
+++ b/tests/migrations/test_optimizer.py
@@ -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'),
],
)