diff --git a/tests/constraints/models.py b/tests/constraints/models.py index c4450383e7c..245693e847a 100644 --- a/tests/constraints/models.py +++ b/tests/constraints/models.py @@ -19,19 +19,6 @@ class Product(models.Model): check=models.Q(price__gt=0), name="%(app_label)s_%(class)s_price_gt_0", ), - models.CheckConstraint( - check=models.expressions.RawSQL( - "price < %s", (1000,), output_field=models.BooleanField() - ), - name="%(app_label)s_price_lt_1000_raw", - ), - models.CheckConstraint( - check=models.expressions.ExpressionWrapper( - models.Q(price__gt=500) | models.Q(price__lt=500), - output_field=models.BooleanField(), - ), - name="%(app_label)s_price_neq_500_wrap", - ), models.CheckConstraint( check=models.Q( models.Q(unit__isnull=True) | models.Q(unit__in=["μg/mL", "ng/mL"]) diff --git a/tests/constraints/tests.py b/tests/constraints/tests.py index 722483128bc..58960fa5a3c 100644 --- a/tests/constraints/tests.py +++ b/tests/constraints/tests.py @@ -103,18 +103,6 @@ class CheckConstraintTests(TestCase): with self.assertRaises(IntegrityError): Product.objects.create(price=10, discounted_price=7, unit="l") - @skipUnlessDBFeature("supports_table_check_constraints") - def test_database_constraint_expression(self): - Product.objects.create(price=999, discounted_price=5) - with self.assertRaises(IntegrityError): - Product.objects.create(price=1000, discounted_price=5) - - @skipUnlessDBFeature("supports_table_check_constraints") - def test_database_constraint_expressionwrapper(self): - Product.objects.create(price=499, discounted_price=5) - with self.assertRaises(IntegrityError): - Product.objects.create(price=500, discounted_price=5) - @skipUnlessDBFeature( "supports_table_check_constraints", "can_introspect_check_constraints" ) @@ -122,8 +110,6 @@ class CheckConstraintTests(TestCase): constraints = get_constraints(Product._meta.db_table) for expected_name in ( "price_gt_discounted_price", - "constraints_price_lt_1000_raw", - "constraints_price_neq_500_wrap", "constraints_product_price_gt_0", ): with self.subTest(expected_name): diff --git a/tests/migrations/test_operations.py b/tests/migrations/test_operations.py index 4e639abda21..610a8b53ce3 100644 --- a/tests/migrations/test_operations.py +++ b/tests/migrations/test_operations.py @@ -468,6 +468,48 @@ class OperationTests(OperationTestBase): self.assertEqual(definition[1], []) self.assertEqual(definition[2]["options"]["constraints"], [check_constraint]) + @skipUnlessDBFeature("supports_table_check_constraints") + def test_create_model_with_boolean_expression_in_check_constraint(self): + app_label = "test_crmobechc" + rawsql_constraint = models.CheckConstraint( + check=models.expressions.RawSQL( + "price < %s", (1000,), output_field=models.BooleanField() + ), + name=f"{app_label}_price_lt_1000_raw", + ) + wrapper_constraint = models.CheckConstraint( + check=models.expressions.ExpressionWrapper( + models.Q(price__gt=500) | models.Q(price__lt=500), + output_field=models.BooleanField(), + ), + name=f"{app_label}_price_neq_500_wrap", + ) + operation = migrations.CreateModel( + "Product", + [ + ("id", models.AutoField(primary_key=True)), + ("price", models.IntegerField(null=True)), + ], + options={"constraints": [rawsql_constraint, wrapper_constraint]}, + ) + + project_state = ProjectState() + new_state = project_state.clone() + operation.state_forwards(app_label, new_state) + # Add table. + self.assertTableNotExists(app_label) + with connection.schema_editor() as editor: + operation.database_forwards(app_label, editor, project_state, new_state) + self.assertTableExists(f"{app_label}_product") + insert_sql = f"INSERT INTO {app_label}_product (id, price) VALUES (%d, %d)" + with connection.cursor() as cursor: + with self.assertRaises(IntegrityError): + cursor.execute(insert_sql % (1, 1000)) + cursor.execute(insert_sql % (1, 999)) + with self.assertRaises(IntegrityError): + cursor.execute(insert_sql % (2, 500)) + cursor.execute(insert_sql % (2, 499)) + def test_create_model_with_partial_unique_constraint(self): partial_unique_constraint = models.UniqueConstraint( fields=["pink"],