2010-01-16 100 views
7

通常,最好对给定对象执行单个查询与许多查询。假设我有一堆'儿子'物体,每个物体都有'父亲'。我得到所有的'儿子'对象:在App Engine中访问相关对象密钥而不提取对象

sons = Son.all() 

然后,我想让那群儿子的所有父亲。我做的:

father_keys = {} 
for son in sons: 
    father_keys.setdefault(son.father.key(), None) 

然后,我可以这样做:

fathers = Father.get(father_keys.keys()) 

现在,这个假设son.father.key()实际上并没有去获取的对象。我错了吗?我有一堆代码假定object.related_object.key()实际上并不从数据存储中获取related_object。

我正在做这个对吗?

回答

10

您可以通过在下载App Engine SDK源文件时研究appengine.ext.db的来源找到答案 - 答案是,不,根据需要,没有特殊外壳:__get__方法(第2887行ReferenceProperty描述符的来源在之前被调用知道.key()或其他什么东西稍后会被调用到结果上,所以它只是没有机会做你想要的优化。

然而,见行2929:方法get_value_for_datastore你想要什么做完全!

具体,而不是son.father.key(),使用Son.father.get_value_for_datastore(son)你应该快乐,结果;-)。

+1

踢踢屁股的答案。我的应用程序只有10倍的速度和更便宜:D – 2010-01-16 05:17:15

+0

@Sudhir,很高兴帮助,感谢让我知道它做到了! - ) – 2010-01-16 05:29:31

+0

说到哪些对象在从商店检索时被缓存?因此,如果我在处理程序中执行了Father.get(all_keys),如果我只是将他们的父亲打印出来,运行时是否会尝试再次将它们放入模板中? – 2010-01-16 05:31:32

1

我宁愿穿过儿子,并使用son.parent_key()获得父母的钥匙。

parent_key()

返回如果 这个实例没有父该实例的父实体的键,或无。

Since all the path is saved in the instance's key理论上,没有必要再次命中数据库来获取父的关键。

之后,可以使用db.get()立即得到所有父母的实例

GET(键)

获取任何模型给定一个或多个键,实体或实体。

参数:

键 Key对象或Key对象的列表。

如果提供了一个密钥,则返回值是 适当Model类的实例;如果没有 实体与给定密钥一起存在,则返回None。如果提供了 键列表,则返回值 值是模型 实例的相应列表,当没有 实体存在时用于相应键。