views:

67

answers:

1

Suppose I have

class Foo(db.Model):

  bar = db.ReferenceProperty(Bar)

foo = Foo.all().get()

Is there a way for me to do foo.bar without a query being made to Datastore? The docs say that foo.bar will be an instance of Key, so I would expect to be able to do foo.bar.id() and be able to get the id of the Bar that's associated with foo, but it doesn't seem to work that way.

PS: The part of the docs I'm referring to can be found here:

http://code.google.com/appengine/docs/python/datastore/typesandpropertyclasses.html#ReferenceProperty

and it says this:

"An application can explicitly db.get() the value of a ReferenceProperty (which is a Key) to test whether the referenced entity exists."

+7  A: 

As the docs say,

The ReferenceProperty value can be used as if it were a model instance, and the datastore entity will be fetched and the model instance created when it is first used in this way. Untouched reference properties do not query for unneeded data.

so you're fine as long as you don't touch it, but if you do though it, e.g. with an .id() call as you show, "the datastore entity will be fetched", the docs say. More docs are here, but they don't show a way to magically get the id without fetching, either.

I have not tried, but you might be able to use the get_value_for_datastore of the property to get "the Python-native value of the property" which I believe is indeed a Key -- whose id() method should be callable without datastore fetches. Have you tried that?

Alex Martelli
get_value_for_datastore is indeed the correct method - specifically, ModelClass.property.get_value_for_datastore(entity).
Nick Johnson
Thanks, Alex. I read that part of the docs too. To me, it's not clear that doing foo.bar.id() would automatically go to Datastore, because it says "as if it were a model instance". I thought it might be the case that foo.bar returned a proxy, which wouldn't automatically go to Datastore, unless it really needed to, which wouldn't be the case if I were to do foo.bar.id(), since that information is part of foo itself.
allyourcode
This proves that is good idea if you plan to store binary data in some kind, to split it in 2 kinds and refer to the one containing the meta data but not the binary data, because fetching smaller entities is faster the fetching larger ones.
Ilian Iliev