Opened 2 years ago

Closed 2 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: master
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 Changed 2 years ago by Carlton Gibson

Triage Stage: UnreviewedAccepted

comment:2 Changed 2 years ago by Ian Foote

Cc: Ian Foote added

comment:3 Changed 2 years ago by Simon Charette

Has patch: set
Owner: Simon Charette deleted
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 Changed 2 years ago by Ian Foote

Owner: set to Ian Foote
Status: newassigned

comment:5 Changed 2 years ago by Tim Graham <timograham@…>

In 24dc7d8:

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

comment:6 Changed 2 years ago by Tim Graham <timograham@…>

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 Changed 2 years ago by Tim Graham <timograham@…>

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