appengine:缓存的引用属性?

Fel*_*ffa 3 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()
Run Code Online (Sandbox Code Playgroud)

然后我创造了许多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)
Run Code Online (Sandbox Code Playgroud)

现在,如果我想迭代所有Many的,读取它们的few价值,我会这样做:

for many in Many.all().fetch(1000):
  print "%s" % many.few.year
Run Code Online (Sandbox Code Playgroud)

问题是:

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

正如一篇评论中所述:我知道memcache,但是当我通过引用调用另一个实体时,我不确定如何"注入"它.

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

Nic*_*son 8

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

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

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

keys = [MyModel.ref.get_value_for_datastore(x) for x in referers]
referees = db.get(keys)
Run Code Online (Sandbox Code Playgroud)

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