Opened 5 years ago

Closed 5 years ago

#31646 closed New feature (wontfix)

Support annotated check constraints.

Reported by: Tonye Jack Owned by: nobody
Component: Database layer (models, ORM) Version: 2.2
Severity: Normal Keywords: check-constraints, model constraints
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

With the current Implementation of https://docs.djangoproject.com/en/2.2/ref/models/constraints/#checkconstraint there's currently no documented support for using annotated fields directly in the check constraint definition.

Created a sample repo https://github.com/jackton1/django-check-constraint which describes more on the possible use case to enable more complex check constraint definition which can be used directly.

Use Case.

UDF

CREATE OR REPLACE FUNCTION public.non_null_count(VARIADIC arg_array ANYARRAY)
  RETURNS BIGINT AS
  $$
    SELECT COUNT(x) FROM UNNEST($1) AS x
  $$ LANGUAGE SQL IMMUTABLE;


Expected SQL

ALTER TABLE app_name_test_modoel ADD CONSTRAINT app_name_test_model_optional_field_provided
    CHECK(non_null_count(amount::integer , amount_off::integer, percentage::integer) = 1);

Change History (2)

comment:1 by Tonye Jack, 5 years ago

Needs documentation: set
Needs tests: set

comment:2 by Simon Charette, 5 years ago

Easy pickings: unset
Needs documentation: unset
Needs tests: unset
Resolution: wontfix
Status: newclosed

CheckConstraint accepts any boolean expression since Django 3.1+ so this particular one can be expressed using RawSQL

CheckConstraint(
    check=RawSQL(
        'non_null_count(amount::integer , amount_off::integer, percentage::integer) = 1',
        output_field=models.BooleanField(),
     )
)

Or event Func, Cast, and Exact.

non_null_count = Func(Cast('amount', models.IntegerField()), Cast('amount_off', models.IntegerField()), Cast('percentage', models.IntegerField()), function='non_null_count')
CheckConstraint(
    check=Exact(non_null_count, 1),
)
Note: See TracTickets for help on using tickets.
Back to Top