Hmm, I'm not sure about this. On the one hand, during the migrations work I
refactored check constraints for the existing stuff (e.g.
PostitiveIntegerField) out of the type string and into a separate check
constraints string, so some of the work is already there, especially around
making sure they're present on field alteration.

On the other hand, check constraints vary wildly from database to database
- MySQL doesn't have them, SQLite has a basic version in later versions
only and parses but ignores them in earlier versions, PostgreSQL has full
support and Oracle has them too but with a different set of functions to
PostgreSQL, so it's unlikely anything other than simple comparison would be
portable.

For that reason, I wouldn't be the fan of the exploded syntax you've given;
I think I'd rather just be able to supply a list of strings for my
constraints that are SQL themselves; there's no real benefit to abstraction
here, and removing it doubtless removes a lot of code and bugs. Otherwise,
I think I'd be +0.

Andrew


On Tue, Apr 1, 2014 at 4:07 AM, schinckel <m...@schinckel.net> wrote:

> Some years ago, I discussed adding database-level check constraints into
> django:
> https://groups.google.com/forum/#!topic/django-developers/OJN5kpcseAg
>
> There is also an issue: https://code.djangoproject.com/ticket/11964
>
> I'm thinking about revisiting this, and wanted to get some discussion
> going about if this is a viable thing to do, and what it might look like.
>
>
> Django already uses check constraints with PositiveIntegerField and
> friends, and at first blush I thought we might be able to co-opt some of
> that (indeed, I've got an internal monkey-patch that does, with some level
> of success). However, other than the fact there is already a
> 'sql_create_check' string, the actual python code that creates the check
> constraint probably isn't that usable in this context. Also, I like the
> idea of having more complex constraints (postgres has EXCLUDE constraints,
> but I don't know if there is an equivalent for other backends).
>
>
> The approach that I am thinking of could see a syntax similar to:
>
>
>     class MyModel(models.Model):
>         start = models.DateField()
>         finish = models.DateField(constraints=[('check', '> start')])
>         user = models.ForeignKey('auth.User')
>
> This maps directly to creating a check constraint on the table:
>
>      ALTER TABLE "myapp_mymodel" ADD CONSTRAINT CHECK (finish > start)
>
> And, on the same model, a more complex constraint could look like:
>
>
>         class Meta:
>             constraints = [
>                 ('exclude', [
>                     ('overlaps', ['start','finish']),
>                     ('equal', 'user')
>                 ])
>            ]
>
> I'm still unsure of the best way to describe this: it's supposed to mean:
>
>        ALTER TABLE "myapp_mymodel" ADD EXCLUDE USING gist
> (daterange(start, finish) WITH &&, user_id WITH =)
>
> (but the python syntax is obviously immaterial at this stage).
>
>
> Obviously, we can't just rely on the database to do the validation for us:
> it will just raise DatabaseErrors when something fails to validate anyway,
> so we would want to handle this stuff in django's validation framework.
>
> One possibility, at least with the field-based check constraint, would be
> to automatically add a field validator in the case of a CHECK constraint,
> however in the case of an EXCLUDE constraint, we can't really validate
> _without_ hitting the database. Does this mean we should treat EXCLUDE-type
> constraints as something that is beyond the scope of Django?
>
>
>
> With the new migrations framework, it's actually trivial to write a
> migration to add this type of constraint (or the check constraint), and a
> pre_save signal handler in conjunction with that would get 90% of the way,
> but it's still going to be open to a race condition anyway - the only way
> to actually do that is to try to save the object and see what the database
> says.
>
>
> So, I guess I'm asking: is it worth pursuing this further, either in part
> or full?
>
> Matt.
>
>  --
> You received this message because you are subscribed to the Google Groups
> "Django developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to django-developers+unsubscr...@googlegroups.com.
> To post to this group, send email to django-developers@googlegroups.com.
> Visit this group at http://groups.google.com/group/django-developers.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/django-developers/250ed272-198a-478f-b2ce-920afcf533a2%40googlegroups.com<https://groups.google.com/d/msgid/django-developers/250ed272-198a-478f-b2ce-920afcf533a2%40googlegroups.com?utm_medium=email&utm_source=footer>
> .
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to django-developers+unsubscr...@googlegroups.com.
To post to this group, send email to django-developers@googlegroups.com.
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/CAFwN1upE1kAq9X9vNTVUVdNDj%3DXS26-iESOekwWZ801sQ6FxBw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to