Parcourir la source

Refs #34534 -- Reduced Add/RemoveConstraint and Add/RenameIndex operations when optimizing migrations.

Akash Kumar Sen il y a 1 an
Parent
commit
92f0017133
3 fichiers modifiés avec 64 ajouts et 0 suppressions
  1. 1 0
      AUTHORS
  2. 12 0
      django/db/migrations/operations/models.py
  3. 51 0
      tests/migrations/test_optimizer.py

+ 1 - 0
AUTHORS

@@ -34,6 +34,7 @@ answer newbie questions, and generally made Django that much better:
     Ahmed Eltawela <https://github.com/ahmedabt>
     ajs <adi@sieker.info>
     Akash Agrawal <akashrocksha@gmail.com>
+    Akash Kumar Sen <akashkumarsen4@gmail.com>
     Akis Kesoglou <akiskesoglou@gmail.com>
     Aksel Ethem <aksel.ethem@gmail.com>
     Akshesh Doshi <aksheshdoshi+django@gmail.com>

+ 12 - 0
django/db/migrations/operations/models.py

@@ -929,6 +929,9 @@ class AddIndex(IndexOperation):
     def reduce(self, operation, app_label):
         if isinstance(operation, RemoveIndex) and self.index.name == operation.name:
             return []
+        if isinstance(operation, RenameIndex) and self.index.name == operation.old_name:
+            self.index.name = operation.new_name
+            return [AddIndex(model_name=self.model_name, index=self.index)]
         return super().reduce(operation, app_label)
 
 
@@ -1164,6 +1167,15 @@ class AddConstraint(IndexOperation):
     def migration_name_fragment(self):
         return "%s_%s" % (self.model_name_lower, self.constraint.name.lower())
 
+    def reduce(self, operation, app_label):
+        if (
+            isinstance(operation, RemoveConstraint)
+            and self.model_name_lower == operation.model_name_lower
+            and self.constraint.name == operation.name
+        ):
+            return []
+        return super().reduce(operation, app_label)
+
 
 class RemoveConstraint(IndexOperation):
     option_name = "constraints"

+ 51 - 0
tests/migrations/test_optimizer.py

@@ -2,6 +2,7 @@ from django.db import migrations, models
 from django.db.migrations import operations
 from django.db.migrations.optimizer import MigrationOptimizer
 from django.db.migrations.serializer import serializer_factory
+from django.db.models.functions import Abs
 from django.test import SimpleTestCase
 
 from .models import EmptyManager, UnicodeModel
@@ -1159,6 +1160,38 @@ class OptimizerTests(SimpleTestCase):
             ]
         )
 
+    def test_add_rename_index(self):
+        tests = [
+            models.Index(fields=["weight", "pink"], name="mid_name"),
+            models.Index(Abs("weight"), name="mid_name"),
+            models.Index(
+                Abs("weight"), name="mid_name", condition=models.Q(weight__gt=0)
+            ),
+        ]
+        for index in tests:
+            with self.subTest(index=index):
+                renamed_index = index.clone()
+                renamed_index.name = "new_name"
+                self.assertOptimizesTo(
+                    [
+                        migrations.AddIndex("Pony", index),
+                        migrations.RenameIndex(
+                            "Pony", new_name="new_name", old_name="mid_name"
+                        ),
+                    ],
+                    [
+                        migrations.AddIndex("Pony", renamed_index),
+                    ],
+                )
+                self.assertDoesNotOptimize(
+                    [
+                        migrations.AddIndex("Pony", index),
+                        migrations.RenameIndex(
+                            "Pony", new_name="new_name", old_name="other_name"
+                        ),
+                    ],
+                )
+
     def test_add_remove_index(self):
         self.assertOptimizesTo(
             [
@@ -1173,6 +1206,24 @@ class OptimizerTests(SimpleTestCase):
             [],
         )
 
+    def test_add_remove_constraint(self):
+        gt_constraint = models.CheckConstraint(
+            check=models.Q(pink__gt=2), name="constraint_pony_pink_gt_2"
+        )
+        self.assertOptimizesTo(
+            [
+                migrations.AddConstraint("Pony", gt_constraint),
+                migrations.RemoveConstraint("Pony", gt_constraint.name),
+            ],
+            [],
+        )
+        self.assertDoesNotOptimize(
+            [
+                migrations.AddConstraint("Pony", gt_constraint),
+                migrations.RemoveConstraint("Pony", "other_name"),
+            ],
+        )
+
     def test_create_model_add_index(self):
         self.assertOptimizesTo(
             [