#11964: Add the ability to use database-level CHECK CONSTRAINTS
-------------------------------------+-------------------------------------
     Reporter:  Matthew Schinckel    |                    Owner:  Ian Foote
         Type:  New feature          |                   Status:  closed
    Component:  Database layer       |                  Version:  master
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:  fixed
     Keywords:  check constraint     |             Triage Stage:  Ready for
                                     |  checkin
    Has patch:  1                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------

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>
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 post to this group, send email to django-updates@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/067.266099f2d4c03222c262b70d524dce1b%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to