如何在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无助于优化此调用。
答案 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)
问题是:
memcache的详细信息位于http://code.google.com/appengine/docs/python/memcache/usingmemcache.html