mirror of https://github.com/django/django.git
Fixed #34060 -- Fixed migrations crash when adding check constraints with JSONField __exact lookup on Oracle.
This commit is contained in:
parent
22285d366c
commit
c991602ce5
|
@ -347,9 +347,10 @@ END;
|
|||
def lookup_cast(self, lookup_type, internal_type=None):
|
||||
if lookup_type in ("iexact", "icontains", "istartswith", "iendswith"):
|
||||
return "UPPER(%s)"
|
||||
if (
|
||||
lookup_type != "isnull" and internal_type in ("BinaryField", "TextField")
|
||||
) or (lookup_type == "exact" and internal_type == "JSONField"):
|
||||
if lookup_type != "isnull" and internal_type in (
|
||||
"BinaryField",
|
||||
"TextField",
|
||||
):
|
||||
return "DBMS_LOB.SUBSTR(%s)"
|
||||
return "%s"
|
||||
|
||||
|
|
|
@ -106,6 +106,13 @@ class DatabaseFeatures(BaseDatabaseFeatures):
|
|||
"test_group_by_nested_expression_with_params",
|
||||
}
|
||||
)
|
||||
if not is_psycopg3:
|
||||
expected_failures.update(
|
||||
{
|
||||
"constraints.tests.CheckConstraintTests."
|
||||
"test_validate_jsonfield_exact",
|
||||
}
|
||||
)
|
||||
return expected_failures
|
||||
|
||||
@cached_property
|
||||
|
|
|
@ -310,6 +310,11 @@ class JSONExact(lookups.Exact):
|
|||
rhs %= tuple(func)
|
||||
return rhs, rhs_params
|
||||
|
||||
def as_oracle(self, compiler, connection):
|
||||
lhs, lhs_params = self.process_lhs(compiler, connection)
|
||||
rhs, rhs_params = self.process_rhs(compiler, connection)
|
||||
return f"JSON_EQUAL({lhs}, {rhs})", (*lhs_params, *rhs_params)
|
||||
|
||||
|
||||
class JSONIContains(CaseInsensitiveMixin, lookups.IContains):
|
||||
pass
|
||||
|
|
|
@ -365,6 +365,20 @@ class CheckConstraintTests(TestCase):
|
|||
constraint_with_pk.validate(ChildModel, ChildModel(id=1, age=1))
|
||||
constraint_with_pk.validate(ChildModel, ChildModel(pk=1, age=1), exclude={"pk"})
|
||||
|
||||
@skipUnlessDBFeature("supports_json_field")
|
||||
def test_validate_jsonfield_exact(self):
|
||||
data = {"release": "5.0.2", "version": "stable"}
|
||||
json_exact_constraint = models.CheckConstraint(
|
||||
check=models.Q(data__version="stable"),
|
||||
name="only_stable_version",
|
||||
)
|
||||
json_exact_constraint.validate(JSONFieldModel, JSONFieldModel(data=data))
|
||||
|
||||
data = {"release": "5.0.2", "version": "not stable"}
|
||||
msg = f"Constraint “{json_exact_constraint.name}” is violated."
|
||||
with self.assertRaisesMessage(ValidationError, msg):
|
||||
json_exact_constraint.validate(JSONFieldModel, JSONFieldModel(data=data))
|
||||
|
||||
|
||||
class UniqueConstraintTests(TestCase):
|
||||
@classmethod
|
||||
|
|
|
@ -2803,6 +2803,40 @@ class SchemaTests(TransactionTestCase):
|
|||
DurationModel.objects.create(duration=datetime.timedelta(minutes=4))
|
||||
DurationModel.objects.create(duration=datetime.timedelta(minutes=10))
|
||||
|
||||
@skipUnlessDBFeature(
|
||||
"supports_column_check_constraints",
|
||||
"can_introspect_check_constraints",
|
||||
"supports_json_field",
|
||||
)
|
||||
@isolate_apps("schema")
|
||||
def test_check_constraint_exact_jsonfield(self):
|
||||
class JSONConstraintModel(Model):
|
||||
data = JSONField()
|
||||
|
||||
class Meta:
|
||||
app_label = "schema"
|
||||
|
||||
with connection.schema_editor() as editor:
|
||||
editor.create_model(JSONConstraintModel)
|
||||
self.isolated_local_models = [JSONConstraintModel]
|
||||
constraint_name = "check_only_stable_version"
|
||||
constraint = CheckConstraint(
|
||||
check=Q(data__version="stable"),
|
||||
name=constraint_name,
|
||||
)
|
||||
JSONConstraintModel._meta.constraints = [constraint]
|
||||
with connection.schema_editor() as editor:
|
||||
editor.add_constraint(JSONConstraintModel, constraint)
|
||||
constraints = self.get_constraints(JSONConstraintModel._meta.db_table)
|
||||
self.assertIn(constraint_name, constraints)
|
||||
with self.assertRaises(IntegrityError), atomic():
|
||||
JSONConstraintModel.objects.create(
|
||||
data={"release": "5.0.2dev", "version": "dev"}
|
||||
)
|
||||
JSONConstraintModel.objects.create(
|
||||
data={"release": "5.0.3", "version": "stable"}
|
||||
)
|
||||
|
||||
@skipUnlessDBFeature(
|
||||
"supports_column_check_constraints", "can_introspect_check_constraints"
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue