#35594: Add support for non-distinct NULL expressions to
UniqueConstraint.validate()
-------------------------------------+-------------------------------------
     Reporter:  Mark Gensler         |                    Owner:  (none)
         Type:  New feature          |                   Status:  new
    Component:  Database layer       |                  Version:  5.0
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:
     Keywords:  uniqueconstraint     |             Triage Stage:
  nulls_distinct                     |  Unreviewed
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Description changed by Mark Gensler:

Old description:

> Expressions which evaluate to `NULL` within
> `UniqueConstraint(*expressions, nulls_distinct=False)` are still treated
> as distinct by `UniqueConstraint.validate()`. This means a
> `ValidationError` is not raised when it should be.
>
> Similarly, if the database connection uses
> `interprets_empty_strings_as_nulls` this is also ignored by
> `.validate()`.
>
> Should #35575 be merged, this problem would also extend to any
> `GeneratedField` included in `UniqueConstraint(fields=[...],
> nulls_distinct=False)`.
>
> E.g.
>
> {{{
> class Book(models.Model):
>     name = CharField(max_length=255, null=True)
>
>     class Meta:
>         constraints = [
>             UniqueConstraint(F("name"), nulls_distinct=False,
> name="book_name_null_unique")
>         ]
> }}}
> then
> {{{
> > Book.objects.create(name=None)
> > book = Book(name=None)
> > book.full_clean() # Should raise a `ValidationError` but doesn't.
> > book.save()  # The database raises an `IntegrityError`.
> }}}
>
> This ticket was raised following discussion in
> https://github.com/django/django/pull/18356#pullrequestreview-2166340541

New description:

 Expressions which evaluate to `NULL` within
 `UniqueConstraint(*expressions, nulls_distinct=False)` are still treated
 as distinct by `UniqueConstraint.validate()`. This means a
 `ValidationError` is not raised when it should be.

 Similarly, if the database connection uses
 `interprets_empty_strings_as_nulls` this is also ignored by `.validate()`.

 Should #35575 be merged, this problem would also extend to any
 `GeneratedField` included in `UniqueConstraint(fields=[...],
 nulls_distinct=False)`.

 E.g.

 {{{
 class Book(models.Model):
     name = CharField(max_length=255, null=True, blank=True)

     class Meta:
         constraints = [
             UniqueConstraint(F("name"), nulls_distinct=False,
 name="book_name_null_unique")
         ]
 }}}
 then
 {{{
 > Book.objects.create(name=None)
 > book = Book(name=None)
 > book.full_clean() # Should raise a `ValidationError` but doesn't.
 > book.save()  # The database raises a `UniqueViolation`.
 }}}

 This ticket was raised following discussion in
 https://github.com/django/django/pull/18356#pullrequestreview-2166340541

--
-- 
Ticket URL: <https://code.djangoproject.com/ticket/35594#comment:1>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/01070190a1ede338-55644c66-e3f3-4576-b571-e428f2c84f65-000000%40eu-central-1.amazonses.com.

Reply via email to