Opened 18 months ago

Closed 18 months ago

Last modified 18 months ago

#34149 closed Bug (fixed)

Postgres "ExclusionConstraint with conditions cannot be deferred." seems wrong

Reported by: Márton Salomváry Owned by: Márton Salomváry
Component: contrib.postgres Version: 4.1
Severity: Normal Keywords:
Cc: Lily Foote Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When attempting to add a constraint to a model that looks something like this:

ExclusionConstraint(
                name="my_constraint",
                expressions=[
                    ("is_default", RangeOperators.EQUAL),
                ],
                condition=Q(is_default=False),
                deferrable=Deferrable.DEFERRED,
            )

makemigrations fails with the following error:

    ExclusionConstraint(
  File "django/contrib/postgres/constraints.py", line 55, in __init__
    raise ValueError("ExclusionConstraint with conditions cannot be deferred.")
ValueError: ExclusionConstraint with conditions cannot be deferred.

However PostgreSQL 14.5 seems to be perfectly fine with the following:

ALTER TABLE my_model
    ADD CONSTRAINT my_constraint
        EXCLUDE (is_default WITH =)
        WHERE (is_default = TRUE)
        INITIALLY DEFERRED;

I've tried to figure out why this restriction may be in place but neither other parts of Django nor PostgreSQL itself seem to require deferred exclusion constraints to not have a condition.

The commit that added this also does not seem to explain the situation: https://github.com/django/django/commit/b4068bc65636cca6c2905aa8c40bea69bb0e4245

Maybe an accidental copypaste from here? https://github.com/django/django/blob/35911078fa40eb35859832987fedada76963c01e/django/db/models/constraints.py#L153-L154

Change History (9)

comment:1 by Simon Charette, 18 months ago

Triage Stage: UnreviewedAccepted

I think this is effectively a bug due to copy-pasting.

Django implements partial unique constraints using partial unique indices which lack support for the constraint specific options.

Exclusion constraint use proper CONSTRAINT syntax so I don't see why they couldn't support deferral specifiers.

Would you be willing to submit a patch to correct the issue?

comment:2 by Bhuvnesh, 18 months ago

Owner: set to Bhuvnesh
Status: newassigned

comment:3 by Mariusz Felisiak, 18 months ago

Cc: Lily Foote added

comment:4 by Márton Salomváry, 18 months ago

comment:5 by Márton Salomváry, 18 months ago

Owner: changed from Bhuvnesh to Márton Salomváry

comment:6 by Mariusz Felisiak, 18 months ago

Has patch: set
Needs tests: set

comment:7 by Mariusz Felisiak, 18 months ago

Needs tests: unset
Triage Stage: AcceptedReady for checkin

comment:8 by Mariusz Felisiak <felisiak.mariusz@…>, 18 months ago

Resolution: fixed
Status: assignedclosed

In d6cbf39:

Fixed #34149 -- Allowed adding deferrable conditional exclusion constraints on PostgreSQL.

comment:9 by Simon Charette, 18 months ago

Bhuvnesh, it's great that you are enthusiastic about fixing issues but you might want to give reporters a chance to reply on whether or not they want to provide a patch themselves before assigning the ticket to you.

Note: See TracTickets for help on using tickets.
Back to Top