In general, it’s better to do a single query vs. many queries for a given object. Let’s say I have a bunch of ‘son’ objects each with a ‘father’. I get all the ‘son’ objects:
sons = Son.all()
Then, I’d like to get all the fathers for that group of sons. I do:
father_keys = {}
for son in sons:
father_keys.setdefault(son.father.key(), None)
Then I can do:
fathers = Father.get(father_keys.keys())
Now, this assumes that son.father.key() doesn’t actually go fetch the object. Am I wrong on this? I have a bunch of code that assumes the object.related_object.key() doesn’t actually fetch related_object from the datastore.
Am I doing this right?
You can find the answer by studying the sources of appengine.ext.db in your download of the App Engine SDK sources — and the answer is, no, there’s no special-casing as you require: the
__get__method (line 2887 in the sources for the 1.3.0 SDK) of theReferencePropertydescriptor gets invoked before knowing if.key()or anything else will later be invoked on the result, so it just doesn’t get a chance to do the optimization you’d like.However, see line 2929: method
get_value_for_datastoredoes do exactly what you want!Specifically, instead of
son.father.key(), useSon.father.get_value_for_datastore(son)and you should be much happier as a result;-).