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.
For more options, visit https://groups.google.com/d/optout.

Reply via email to