Refs #34534 -- Reduced constraint operations with Meta.constraints when optimizing migrations.

This commit is contained in:
Ben Cail 2024-01-31 15:25:30 -05:00 committed by Mariusz Felisiak
parent 9c5e382b98
commit 8b7ddd1b62
3 changed files with 115 additions and 9 deletions

View File

@ -342,6 +342,40 @@ class CreateModel(ModelOperation):
managers=self.managers,
),
]
elif isinstance(operation, AddConstraint):
return [
CreateModel(
self.name,
fields=self.fields,
options={
**self.options,
"constraints": [
*self.options.get("constraints", []),
operation.constraint,
],
},
bases=self.bases,
managers=self.managers,
),
]
elif isinstance(operation, RemoveConstraint):
options_constraints = [
constraint
for constraint in self.options.get("constraints", [])
if constraint.name != operation.name
]
return [
CreateModel(
self.name,
fields=self.fields,
options={
**self.options,
"constraints": options_constraints,
},
bases=self.bases,
managers=self.managers,
),
]
return super().reduce(operation, app_label)

View File

@ -2762,21 +2762,23 @@ class AutodetectorTests(BaseAutodetectorTests):
},
)
changes = self.get_changes([], [author])
added_constraint = models.CheckConstraint(
constraint = models.CheckConstraint(
check=models.Q(name__contains="Bob"), name="name_contains_bob"
)
# Right number of migrations?
self.assertEqual(len(changes["otherapp"]), 1)
# Right number of actions?
migration = changes["otherapp"][0]
self.assertEqual(len(migration.operations), 2)
self.assertEqual(len(migration.operations), 1)
# Right actions order?
self.assertOperationTypes(
changes, "otherapp", 0, ["CreateModel", "AddConstraint"]
)
self.assertOperationAttributes(changes, "otherapp", 0, 0, name="Author")
self.assertOperationTypes(changes, "otherapp", 0, ["CreateModel"])
self.assertOperationAttributes(
changes, "otherapp", 0, 1, model_name="author", constraint=added_constraint
changes,
"otherapp",
0,
0,
name="Author",
options={"constraints": [constraint]},
)
def test_add_constraints(self):
@ -4177,7 +4179,7 @@ class AutodetectorTests(BaseAutodetectorTests):
changes,
"testapp",
0,
["CreateModel", "AddConstraint"],
["CreateModel"],
)
self.assertOperationAttributes(
changes,
@ -4185,7 +4187,14 @@ class AutodetectorTests(BaseAutodetectorTests):
0,
0,
name="Author",
options={"order_with_respect_to": "book"},
options={
"order_with_respect_to": "book",
"constraints": [
models.CheckConstraint(
check=models.Q(_order__gt=1), name="book_order_gt_1"
)
],
},
)
def test_add_model_order_with_respect_to_index(self):

View File

@ -1326,3 +1326,66 @@ class OptimizerTests(SimpleTestCase):
),
],
)
def test_create_model_add_constraint(self):
gt_constraint = models.CheckConstraint(
check=models.Q(weight__gt=0), name="pony_weight_gt_0"
)
self.assertOptimizesTo(
[
migrations.CreateModel(
name="Pony",
fields=[
("weight", models.IntegerField()),
],
),
migrations.AddConstraint("Pony", gt_constraint),
],
[
migrations.CreateModel(
name="Pony",
fields=[
("weight", models.IntegerField()),
],
options={"constraints": [gt_constraint]},
),
],
)
def test_create_model_remove_constraint(self):
self.assertOptimizesTo(
[
migrations.CreateModel(
name="Pony",
fields=[
("weight", models.IntegerField()),
],
options={
"constraints": [
models.CheckConstraint(
check=models.Q(weight__gt=0), name="pony_weight_gt_0"
),
models.UniqueConstraint(
"weight", name="pony_weight_unique"
),
],
},
),
migrations.RemoveConstraint("Pony", "pony_weight_gt_0"),
],
[
migrations.CreateModel(
name="Pony",
fields=[
("weight", models.IntegerField()),
],
options={
"constraints": [
models.UniqueConstraint(
"weight", name="pony_weight_unique"
),
]
},
),
],
)