On Thu, Mar 17, 2011 at 09:33:43AM -0500, Jacob Kaplan-Moss wrote:
> On Wed, Mar 16, 2011 at 4:24 AM, Johannes Dollinger
> <emulb...@googlemail.com> wrote:
> > I would be nice if support for composite primary keys would be
> > implemented as a special case of general composite fields. There
> > would be no need for new Meta options:
> >
> > class Foo(Model):
> >    x = models.FloatField()
> >    y = models.FloatField()
> >    coords = models.CompositeField((x, y), db_index=True)
> >    a = models.ForeignKey(A)
> >    b = models.ForeignKey(B)
> >    pair = models.CompositeField((a, b), primary_key=True)
> >
> > A CompositeField descriptor would then return a namedtuple of its
> > values and would support queries:
> >
> >    filter(coords__x=42)
> >    filter(coords=(1,2))
> >
> > Adding the individual fields may be optional, e.g,
> > CompositeField((FloatField(), FloatField()), db_index=True).
> >
> > This has been proposed before:
> > http://groups.google.com/group/django-developers/browse_thread/thread/32f861c8bd5366a5
I must have overlooked this thread before...

> I like this quite a bit. Of all the various syntaxes proposed here so
> far, this is the first one that feels like it "fits" with the rest of
> Django, and the first one I'm +1 on.
I agree as well. This approach looks much cleaner from the design
perspective. At least the syntax is more consistent than having the
same information scattered throughout the individual fields and
several Meta attributes in different cases.

However, we'd either have a different API for specifying unique
constraints for sets of fields than for composite keys or we'd have
two options for the unique thing. (Or we'd lose backwards
compatibility.) The current API could be simulated by creating an
implicit CompositeField for each unique tuple with a reasonable
name.

A ForeignKey referencing a model with a primary CompositeField could
then act as a CompositeField itself, creating implicit fields unless
explicitly specified. Would this be a good idea? It would make it
easier to mess with the values of the fields directly, possibly
breaking the references to other rows, however, this is possible even
with the way it is now.

There is one thing though that's bothering me a little bit... At a
first glance this looks to me like a lot more work than my original
proposal. Now I'm not sure whether I should try to squeeze it all into
a single project with the primary key support and ForeignKey and
everything or rather just do the CompositeField with proper queryset
support and save the primary keys for a later time. Thoughts?

> I'm sensitive to Christophe's point that a "composite field" doesn't
> map to a relational concept very well, but quite frankly that ship has
> sailed. We've got ManyToManyFields, GenericForeignKeys, and once you
> branch out into the ecosystem you find TagFields, PickleFields (ugh)
> and so forth.
Just a note, my first approach at the composite ForeignKey field would
fall into this category anyway. I think we can't avoid that with this
kind of functionality...

Michal Petrucha

Attachment: signature.asc
Description: Digital signature

Reply via email to