3

如何在 Google App Engine 中缓存参考属性?

例如,假设我有以下模型:

class Many(db.Model):
    few = db.ReferenceProperty(Few) 

class Few(db.Model):
    year = db.IntegerProperty()

然后我创建了许多Many只指向一个的Few

one_few = Few.get_or_insert(year=2009)
Many.get_or_insert(few=one_few)
Many.get_or_insert(few=one_few)
Many.get_or_insert(few=one_few)
Many.get_or_insert(few=one_few)
Many.get_or_insert(few=one_few)
Many.get_or_insert(few=one_few)

现在,如果我想遍历所有Many',读取它们的few值,我会这样做:

for many in Many.all().fetch(1000):
  print "%s" % many.few.year

问题是:

  • 请问每次访问都会many.few触发一次数据库查找吗?
  • 如果是,是否可以在某处缓存,因为每次只需一次查找就足以带来相同的实体?

正如一条评论中所指出的:我知道 memcache,但是当我通过引用调用另一个实体时,我不确定如何“注入”它。

在任何情况下,memcache 都不会有用,因为我需要在执行中进行缓存,而不是在它们之间。使用 memcache 无助于优化此调用。

4

2 回答 2

8

第一次取消引用任何引用属性时,将提取实体 - 即使您之前提取了与不同引用属性关联的同一实体。这涉及数据存储获取操作,它不像查询那样昂贵,但如果可以的话,仍然值得避免。

有一个很好的模块可以在这里添加无缝的实体缓存。它在数据存储的较低级别工作,并将缓存所有数据存储获取,而不仅仅是取消引用 ReferenceProperties。

如果您想一次解析一堆引用属性,还有另一种方法:您可以在一次往返中检索所有键并获取实体,如下所示:

keys = [MyModel.ref.get_value_for_datastore(x) for x in referers]
referees = db.get(keys)

Finally, I've written a library that monkeypatches the db module to locally cache entities on a per-request basis (no memcache involved). It's available, here. One warning, though: It's got unit tests, but it's not widely used, so it could be broken.

于 2009-07-23T21:57:58.527 回答
1

问题是:

  1. 每次访问 many.few 都会触发数据库查找吗?是的。不确定是 1 还是 2 调用
  2. 如果是,是否可以在某处缓存,因为每次只需一次查找就足以带来相同的实体?您应该能够使用 memcache 存储库来执行此操作。这是在 google.appengine.api.memcache 包中。

内存缓存的详细信息在http://code.google.com/appengine/docs/python/memcache/usingmemcache.html

于 2009-07-23T20:18:06.297 回答