appengine:缓存的引用属性?

时间:2009-07-23 19:51:30

标签: python database performance google-app-engine google-cloud-datastore

如何在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无助于优化此调用。

2 个答案:

答案 0 :(得分:8)

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

有一个很好的模块可以添加可用实体的无缝缓存here。它适用于较低级别的数据存储区,并将缓存所有数据存储区获取,而不仅仅是解除引用ReferenceProperties。

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

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

最后,我编写了一个库,可以根据每个请求对db模块进行monkeypatches to本地缓存实体(不涉及内存缓存)。它可用,here。但是有一个警告:它有单元测试,但它没有被广泛使用,所以可能会被打破。

答案 1 :(得分:1)

问题是:

  1. 每次访问many.few会触发数据库查找吗?是。不确定是1还是2来电话
  2. 如果是,是否可以在某处缓存,因为每次只有一次查找应足以带来同一个实体?您应该能够使用memcache存储库来执行此操作。这是在google.appengine.api.memcache包中。
  3. memcache的详细信息位于http://code.google.com/appengine/docs/python/memcache/usingmemcache.html