Opened 9 years ago

Closed 5 months ago

Last modified 6 weeks ago

#11964 closed New feature (fixed)

Add the ability to use database-level CHECK CONSTRAINTS

Reported by: Matthew Schinckel Owned by: Ian Foote
Component: Database layer (models, ORM) Version: master
Severity: Normal Keywords: check constraint
Cc: Danilo Bargen, esigra, gam_phon, python@…, Ryan Hiebert, Michael Wheeler, Pablo Montepagano, Ties de Kock 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

I mentioned adding database level CHECK CONSTRAINTS in a post on django-developers.

http://groups.google.com/group/django-developers/browse_thread/thread/38937992972c7808

Attached to this ticket is a patch that provides the functionality listed in the first post of this thread. This is not complete: it only allows simple constraints, and is missing a complete test suite.

Attachments (1)

check_constraints.diff (15.8 KB) - added by Matthew Schinckel 9 years ago.
Contains patches against trunk that enable check constraints

Download all attachments as: .zip

Change History (40)

Changed 9 years ago by Matthew Schinckel

Attachment: check_constraints.diff added

Contains patches against trunk that enable check constraints

comment:1 Changed 9 years ago by Russell Keith-Magee

Triage Stage: UnreviewedSomeday/Maybe

If we do this, it should be tied into the model validation framework in some way.

comment:2 Changed 9 years ago by Matthew Schinckel

Agreed. The initial patch was made before the changes with model validation had hit. I will get back to this at some stage.

comment:3 Changed 8 years ago by Julien Phalip

Severity: Normal
Type: New feature

comment:4 Changed 7 years ago by Aymeric Augustin

UI/UX: unset

Change UI/UX from NULL to False.

comment:5 Changed 7 years ago by Aymeric Augustin

Easy pickings: unset

Change Easy pickings from NULL to False.

comment:6 Changed 7 years ago by Danilo Bargen

Cc: Danilo Bargen added

comment:7 Changed 4 years ago by Tim Graham

Patch needs improvement: set

comment:8 Changed 4 years ago by esigra

Cc: esigra added

comment:9 Changed 3 years ago by Tim Graham

Summary: Using database-level CHECK CONSTRAINTSAdd the ability to use database-level CHECK CONSTRAINTS
Triage Stage: Someday/MaybeAccepted
Version: 1.1master

comment:10 Changed 3 years ago by gam_phon

Cc: gam_phon added

comment:11 Changed 3 years ago by Rich Rauenzahn

Could/should this feature request also handle this case of constraint I brought up in this thread?

https://code.djangoproject.com/ticket/11964

Basically unique_together doesn't consider a null value unique per SQL spec -- which makes perfect sense in single column indexes and is extended to multi column indexes.

So if someone wanted (A, B, NULL) to be a unique row there would need to be an index built on the first two columns "where <third column> is null"

These SO articles give a better overview:

http://stackoverflow.com/questions/17510261/django-unique-together-constraint-failure
http://dba.stackexchange.com/questions/9759/postgresql-multi-column-unique-constraint-and-null-values

comment:12 Changed 3 years ago by alexpirine

I would also love this feature.

comment:13 Changed 2 years ago by Ian Foote

Cc: python@… added
Owner: changed from nobody to Ian Foote
Status: newassigned

comment:14 Changed 22 months ago by Tim Graham <timograham@…>

In 19b2dfd1:

Refs #11964, #26167 -- Made Expressions deconstructible.

comment:15 Changed 22 months ago by Tim Graham <timograham@…>

In 508b5deb:

Refs #11964 -- Made Q objects deconstructible.

comment:16 Changed 22 months ago by Ian Foote

Needs documentation: set

comment:17 Changed 16 months ago by Ryan Hiebert

Cc: Ryan Hiebert added

comment:18 Changed 16 months ago by Asif Saifuddin Auvi

Needs documentation: unset
Patch needs improvement: unset

comment:19 Changed 14 months ago by Tim Graham

Patch needs improvement: set

comment:20 Changed 14 months ago by Luke Plant

This external project seems to implement this feature:

https://github.com/rapilabs/django-db-constraints

It does some monkey patching that would be unnecessary if this were in core.

comment:21 Changed 13 months ago by Ian Foote

Patch needs improvement: unset

comment:22 Changed 12 months ago by Ian Foote

Now that Django 2 is released, I'd like to see this land. I think I've resolved all the outstanding issues raised on the pull request before. Is the next step to rebase/squash my work in progress commits?

comment:23 Changed 10 months ago by Asif Saifuddin Auvi

Patch needs improvement: set

conflicts needed to be resolved and squash for final review I believe.

comment:24 Changed 10 months ago by Ian Foote

Patch needs improvement: unset

Conflicts fixed and commits squashed.

comment:25 Changed 9 months ago by Michael Wheeler

Cc: Michael Wheeler added

comment:26 Changed 8 months ago by Asif Saifuddin Auvi

Patch needs improvement: set

comment:27 Changed 8 months ago by Tim Graham

Patch needs improvement: unset

Please don't check "Patch needs improvement" only because there's a small merge conflict (as far as I can see, there's no outstanding review comments on the patch).

comment:28 Changed 7 months ago by Pablo Montepagano

Cc: Pablo Montepagano added

comment:29 Changed 6 months ago by Carlton Gibson

Triage Stage: AcceptedReady for checkin

comment:30 Changed 6 months ago by Ties de Kock

Cc: Ties de Kock added
Keywords: constraint added; contsraint removed

comment:31 Changed 5 months ago by Tim Graham <timograham@…>

Resolution: fixed
Status: assignedclosed

In 952f05a6:

Fixed #11964 -- Added support for database check constraints.

comment:32 Changed 5 months ago by Gavin Wahl

Is it now possible to define a field that comes with a check constraint, or can they only be defined at the table level? I'd like to be able to define my own StrictlyPositiveIntegerField.

comment:33 Changed 3 months ago by Tim Graham <timograham@…>

In 9a0e0d96:

Refs #11964 -- Renamed a database check constraint test.

comment:34 Changed 2 months ago by Tim Graham <timograham@…>

In 9142bebf:

Refs #11964 -- Changed CheckConstraint() signature to use keyword-only arguments.

Also renamed the constraint argument to check to better represent which
part of the constraint the provided Q object represents.

comment:35 Changed 2 months ago by Tim Graham <timograham@…>

In bc7e288:

Fixed #29745 -- Based Expression equality on detailed initialization signature.

The old implementation considered objects initialized with an equivalent
signature different if some arguments were provided positionally instead of
as keyword arguments.

Refs #11964, #26167.

comment:36 Changed 8 weeks ago by Scott Stevens

It appears that adding multiple constraints to a table results in only the last being stored.

Reviewing the SQL (./manage.py sqlmigrate), I'm seeing each constraint being added by way of ALTER TABLE, CREATE TABLE, INSERT INTO ... SELECT, DROP TABLE, however only the most recent constraint is added each time, so the previous constraint is dropped with the old table when adding the new one.

Using 38f3de86bd0bfa4c9b57db1237fa55e9fa88bc6e, Python 3.6.6 (Win10x64) with SQLite database.

Should I file a new bug for this?

Last edited 8 weeks ago by Scott Stevens (previous) (diff)

comment:37 Changed 8 weeks ago by Simon Charette

Yeah please file a new ticket Scott and escalate it to release blocker as it's a bug in a yet unreleased version of Django.

This is probably due to the fact SQLite requires a table rebuild on most ALTER TABLE operations.

comment:38 Changed 7 weeks ago by Tim Graham <timograham@…>

In 32da3cfd:

Refs #11964 -- Removed raw SQL from and cleaned up constraint operation tests.

comment:39 Changed 6 weeks ago by Carlton Gibson <carlton.gibson@…>

In 95bda03:

Fixed #29868 -- Retained database constraints on SQLite table rebuilds.

Refs #11964.

Thanks Scott Stevens for testing this upcoming feature and the report.

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