On Sat, Nov 7, 2009 at 1:48 PM, J Meier <jim-goo...@dsdd.org> wrote:
>
> I've implemented a nearly identical solution for this problem before,
> and while it worked, it felt dirty.
>
> It strikes me that the problem is to do with our "surrogate" primary
> key ids, which don't relate to the data at all. For most models, this
> is fine. The problem here is that the ids do not meaningfully identify
> particular rows, and so we can't refer to them without psychic id-
> guessing powers.
>
> Wouldn't a simpler solution be to change ContentType and such to have
> meaningful primary keys?

There are three issues here.

Firstly, changing the definition of ContentType to avoid the problem
has been proposed in the past. However, this would be a *massive*
backwards incompatibility. Making this change isn't something we would
do lightly.

Secondly, the "right way" in a relational sense would be to have a
composite primary key over app_label and model. However, Django
doesn't currently support composite primary keys. So - in order to
follow this approach, we would need a finish a major rework of primary
key handling first.

Thirdly, that would solve the problem for ContentType, but not the
general problem. The general problem is that it is possible to
dynamically create data as part of a syncdb trigger, so any
autogenerated primary key isn't useful. Sure - we can change
ContentType to avoid the problem, but that doesn't make the problem go
away for the general case. It's easy to define a model for which an
autogenerated integer primary key is appropriate, which has
dynamically created syncdb content. These are the models that aren't
currently serializable.

> For ContentType, at least, this would require either creating a new
> surrogate primary key that contained both the app and model names, or
> else compound primary key support.
>
> For you example, it would be something like
>
> {
>    "pk": 1,
>    "model": "myapp.mymodel",
>    "fields": {
>         "name": "foobar",
>         "content_type": "otherapp.othermodel"
>    }
> }
>
> Or with a compound key,
> {
>    "pk": 1,
>    "model": "myapp.mymodel",
>    "fields": {
>         "name": "foobar",
>         "content_type": ("otherapp","othermodel")
>    }
> }
>
> This would solve both the serialization and deserialization sides of
> the problem.
>
> Am I off the mark?

Not entirely. The idea of having a surrogate primary key is
interesting - it essence it isn't that far from Option 2 in my
original list.

Option 2 introduced the idea of defining a 'dump_relation' key to Meta
to define the columns that should be used to define serialization. In
essence, this is defining the surrogate primary key for the model. In
most practical uses, this will be either a unique column, or a
unique_together tuple - which means that the grouping will effectively
be a surrogate primary key.

The syntactical difference in your proposal (i.e., 'myapp.mymodel',
rather than {'app_label': 'myapp', 'model': 'mymodel'} requires that
the model provide specific serialization/deserialization tools for
your model.

So if we said that if a model provides a get_surrogate_key() and the
model manager provides a get_instance_by_surrogate_key() method (not
happy with the names, but it's a bikeshed for the moment), the
serializer/deserializer will use those methods instead of to_python()
on the PK for (de)serializing the model.

The downside of this approach is exactly the same as it is for the
original Option 2 - it means you can only define one way to serialize
the model. However, this may not be such a problem as we're expressing
this in terms of surrogate keys, rather than a specific serialization
property that might change with the serialization technique.

And, again - this is actually compatible with Option 1. As syntactic
sugar, we can still include dictionary based lookup syntax if we want
to - we just won't need to provide query based serialization support.

Yours,
Russ Magee %-)

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to