Opened 6 years ago

Closed 5 years ago

#29641 closed New feature (fixed)

Add support for unique constraints to Meta.constraints

Reported by: Simon Charette Owned by: Ian Foote
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords:
Cc: Ian Foote Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Just like Meta.indexes[Index] allows more granularity over Field.db_index=True/ Meta.index_together we should make Meta.constraints[UniqueConstraint] an analog for Field.unique=True/Meta.unique_together.

This ticket proposes to introduce django.db.constraint.UniqueConstraint(fields, name) to allow such constraints to be defined with the sole extra feature of allowing a name to be specified.

The mid-term goal of this feature addition is to rely on the partial indices work (#29547) that is likely to land in 2.2 to allow partial unique constraints to be defined which is a really useful feature.

e.g.

class Tweet(models.Model):
    user = models.ForeignKey(User, models.CASCADE)
    pinned = models.BooleanField(default=False)

    class Meta:
        constraints = [
            UniqueConstraint(
                fields=['user', 'pinned'],
                condition=Q(pinned=True),
                name='pinned_tweet'
            ),
        ]

Adding support for partial constraints should be tracked in a future ticket as this one will focus on refactoring the CheckConstraint work added for #11964 to the definition of different type of constraints.

Change History (7)

comment:1 by Carlton Gibson, 6 years ago

Triage Stage: UnreviewedAccepted

comment:2 by Ian Foote, 6 years ago

Cc: Ian Foote added

comment:3 by Simon Charette, 6 years ago

Has patch: set
Owner: Simon Charette removed
Status: assignednew

Ian started adjusting my initial PR in https://github.com/django/django/pull/10337.

I'd be great to get the commits referencing #29641 in before the 2.2 release as they are mostly adjustments that will be hard to perform if we commit to the currently documented interface.

I'd review it but since I've written a large chunk of this code it's a bit hard for me to do it.

I'm deassigning the ticket given Ian's work so far, feel free to claim the ticket Ian.

comment:4 by Ian Foote, 6 years ago

Owner: set to Ian Foote
Status: newassigned

comment:5 by Tim Graham <timograham@…>, 6 years ago

In 24dc7d8:

Refs #29641 -- Extracted reusable CheckConstraint logic into a base class.

comment:6 by Tim Graham <timograham@…>, 5 years ago

In dba4a63:

Refs #29641 -- Refactored database schema constraint creation.

Added a test for constraint names in the database.

Updated SQLite introspection to use sqlparse to allow reading the
constraint name for table check and unique constraints.

Co-authored-by: Ian Foote <python@…>

comment:7 by Tim Graham <timograham@…>, 5 years ago

Resolution: fixed
Status: assignedclosed

In db13bca6:

Fixed #29641 -- Added support for unique constraints in Meta.constraints.

This constraint is similar to Meta.unique_together but also allows
specifying a name.

Co-authored-by: Ian Foote <python@…>

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