* cc: dbrgn (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:6>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* needs_better_patch: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:7>
* cc: esigra (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:8>
* version: 1.1 => master
* stage: Someday/Maybe => Accepted
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:9>
* cc: gam_phon (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:10>
Comment (by rrauenza):
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
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:11>
Comment (by alexpirine):
I would also love this feature.
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:12>
* owner: nobody => Ian Foote
* status: new => assigned
* cc: python@… (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:13>
Comment (by Tim Graham <timograham@…>):
In [changeset:"19b2dfd1bfe7fd716dd3d8bfa5f972070d83b42f" 19b2dfd1]:
{{{
#!CommitTicketReference repository=""
revision="19b2dfd1bfe7fd716dd3d8bfa5f972070d83b42f"
Refs #11964, #26167 -- Made Expressions deconstructible.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:14>
Comment (by Tim Graham <timograham@…>):
In [changeset:"508b5debfb16843a8443ebac82c1fb91f15da687" 508b5deb]:
{{{
#!CommitTicketReference repository=""
revision="508b5debfb16843a8443ebac82c1fb91f15da687"
Refs #11964 -- Made Q objects deconstructible.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:15>
* needs_docs: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:16>
* cc: Ryan Hiebert (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:17>
* needs_better_patch: 1 => 0
* needs_docs: 1 => 0
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:18>
* needs_better_patch: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:19>
Comment (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.
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:20>
* needs_better_patch: 1 => 0
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:21>
Comment (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?
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:22>
* needs_better_patch: 0 => 1
Comment:
conflicts needed to be resolved and squash for final review I believe.
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:23>
* needs_better_patch: 1 => 0
Comment:
Conflicts fixed and commits squashed.
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:24>
* cc: Michael Wheeler (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:25>
* needs_better_patch: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:26>
* needs_better_patch: 1 => 0
Comment:
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).
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:27>
* cc: Pablo Montepagano (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:28>
* stage: Accepted => Ready for checkin
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:29>
* keywords: check contsraint => check constraint
* cc: Ties de Kock (added)
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:30>
* status: assigned => closed
* resolution: => fixed
Comment:
In [changeset:"952f05a6db2665d83c04075119285f2164b03432" 952f05a6]:
{{{
#!CommitTicketReference repository=""
revision="952f05a6db2665d83c04075119285f2164b03432"
Fixed #11964 -- Added support for database check constraints.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:31>
Comment (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.
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:32>
Comment (by Tim Graham <timograham@…>):
In [changeset:"9a0e0d966a1a317b1b422b5e92949e6d1f33fc2f" 9a0e0d96]:
{{{
#!CommitTicketReference repository=""
revision="9a0e0d966a1a317b1b422b5e92949e6d1f33fc2f"
Refs #11964 -- Renamed a database check constraint test.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:33>
Comment (by Tim Graham <timograham@…>):
In [changeset:"9142bebff2657f2129a2028137f81d09db989968" 9142bebf]:
{{{
#!CommitTicketReference repository=""
revision="9142bebff2657f2129a2028137f81d09db989968"
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.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:34>
Comment (by Tim Graham <timograham@…>):
In [changeset:"bc7e288ca9554ac1a0a19941302dea19df1acd21" bc7e288]:
{{{
#!CommitTicketReference repository=""
revision="bc7e288ca9554ac1a0a19941302dea19df1acd21"
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.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:35>
Comment (by Scott Stevens):
It appears that adding multiple constraints to a table results in only the
last being stored.
Reviewing the SQL (`./manage.py migrate`), 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?
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:36>
Comment (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.
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:37>
Comment (by Tim Graham <timograham@…>):
In [changeset:"32da3cfdf9f25e0a21c0376e94067795380abeae" 32da3cfd]:
{{{
#!CommitTicketReference repository=""
revision="32da3cfdf9f25e0a21c0376e94067795380abeae"
Refs #11964 -- Removed raw SQL from and cleaned up constraint operation
tests.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:38>
Comment (by Carlton Gibson <carlton.gibson@…>):
In [changeset:"95bda03f2da15172cf342f13ba8a77c007b63fbb" 95bda03]:
{{{
#!CommitTicketReference repository=""
revision="95bda03f2da15172cf342f13ba8a77c007b63fbb"
Fixed #29868 -- Retained database constraints on SQLite table rebuilds.
Refs #11964.
Thanks Scott Stevens for testing this upcoming feature and the report.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:39>
Comment (by Balazs Endresz):
> 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.
Looks like positive integer fields have been already defined that way:
https://github.com/django/django/blob/084536a/django/db/models/fields/__init__.py#L637
https://github.com/django/django/blob/084536a/django/db/backends/postgresql/base.py#L95
Similarly, one can add a ''simple'' custom field (that has no additional
arguments):
{{{
class StrictlyPositiveIntegerField(models.PositiveIntegerField):
# NB the db_check method is not documented
def db_check(self, connection):
data = self.db_type_parameters(connection)
return '"%(column)s" > 0' % data
}}}
With a few tweaks it probably could be made to work with custom field args
and CheckConstraints too:
{{{
BaseDatabaseSchemaEditor.sql_create_check = (
# need to drop the check first, otherwise it can't be modified:
'ALTER TABLE %(table)s DROP CONSTRAINT IF EXISTS %(name)s'
'ALTER TABLE %(table)s ADD CONSTRAINT %(name)s CHECK (%(check)s)'
)
class CustomFieldWithArgsAndChecks(models.Field):
... # handle custom args in __init__() and deconstruct() and define
validators too
def db_check(self, connection):
constraint = models.CheckConstraint(check=models.Q(**{
f'{self.name}__gte': self.gte,
f'{self.name}__lte': self.lte,
}), name='')
with connection.schema_editor() as schema_editor:
return constraint._get_check_sql(self.model, schema_editor)
}}}
I wonder if there are any plans to officially support doing that kind of
thing in the future.
Perhaps it isn't too far out of reach now with CheckConstraints in place.
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:40>
Comment (by Mariusz Felisiak <felisiak.mariusz@…>):
In [changeset:"8b3e1b6e9e4ee87fe85b2e5437faf59457e03e62" 8b3e1b6]:
{{{
#!CommitTicketReference repository=""
revision="8b3e1b6e9e4ee87fe85b2e5437faf59457e03e62"
Refs #11964 -- Made constraint support check respect required_db_features.
This will notably silence the warnings issued when running the test
suite on MySQL.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:41>
Comment (by Mariusz Felisiak <felisiak.mariusz@…>):
In [changeset:"306b6875209cfedce2536a6679e69adee7c9bc6a" 306b6875]:
{{{
#!CommitTicketReference repository=""
revision="306b6875209cfedce2536a6679e69adee7c9bc6a"
Refs #11964 -- Removed SimpleCol in favor of Query(alias_cols).
This prevent having to pass simple_col through multiple function calls
by defining whether or not references should be resolved with aliases
at the Query level.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/11964#comment:42>