Google Appengine 一对多及按集合名称查询

1 投票
1 回答
547 浏览
提问于 2025-04-17 12:55

一对多的部分,

http://code.google.com/appengine/articles/modeling.html

他们展示了如何建模这些关系。

class Contact(db.Model):
    # Basic info.
    name = db.StringProperty()
    birth_day = db.DateProperty()

...

class PhoneNumber(db.Model):
    contact = db.ReferenceProperty(Contact,
                                   collection_name='phone_numbers')

...

我觉得,如果你执行以下代码:

scott = Contact(name='Scott')
scott.put()
PhoneNumber(contact=scott,
            phone_type='home',
            number='(650) 555 - 2200').put()
PhoneNumber(contact=scott,
            phone_type='mobile',
            number='(650) 555 - 2201').put()


 for phone in scott.phone_numbers:
     print '%s: %s' % (phone.phone_type, phone.number)

 for phone in scott.phone_numbers:
     print '%s: %s' % (phone.phone_type, phone.number)

上面的第二个for会再次查询数据存储。

如果你在循环中处理“Scott”,并且每次都调用电话号码,这样会执行很多次读取操作。有没有什么方法可以在第一次读取时缓存这些数据,以便在请求的生命周期内使用?还是说需要手动处理?

谢谢。

1 个回答

2

隐式集合 'phone_numbers' 是通过查询构建的,缓存查询结果有点棘手。因为在写入数据后,很难判断哪些缓存的查询结果需要失效。

一种解决方法是使用 ndb 及其缓存支持(http://code.google.com/p/appengine-ndb-experiment/)。从 1.6.2 版本开始,ndb 已经包含在 SDK 里了。

ndb 不会缓存查询结果,但它会缓存通过键获取的实体,因此你可以像这样利用它的缓存(假设 PhoneNumber 和 Contact 继承自 ndb.model.Model):

 phone_number = PhoneNumber(parent=contact_key, number='xxx')
 phone_number.put()
 ....
 phone_numbers = ndb.get_multi(PhoneNumber.query(ancestor=contact_key).fetch(keys_only=True))

请查看这个讨论——注意在 ndb 中执行查询和通过键获取数据时的注意事项:https://groups.google.com/group/appengine-ndb-discuss/browse_thread/thread/89dc6c019347b2a2/7f1db25d76515d07?lnk=gst&q=query+result+caching#7f1db25d76515d07

撰写回答