GAE:有效查询实体及其引用的实体

时间:2016-06-08 19:36:35

标签: google-app-engine google-cloud-datastore app-engine-ndb

我试图在模板视图中有效地返回实体列表及其各自引用的实体。例如

我们正在与两种方式合作:

class Event(ndb.Model):
    """An fun activity or event"""
    name = ndb.StringProperty()
    venue = ndb.KeyProperty()

class Venue(ndb.Model):
    """The venue of an event"""
    name = ndb.StringProperty()
    address = StringProperty()

Event类型通过Venue引用ndb.KeyProperty()。要在模板中显示事件列表及其各自的场地,我可以先执行此查询:

# we can fetch this from memcache
events = Event.query().fetch()

然后,在我看来:

{% for event in events %}
    Event Name: {{event.name}}
    Event Venue: {{event.venue.get().name}}  # is this line costly?
{% endfor %}

通过这种方法,我认为对于每个活动,都会get()呼叫其各自的场地。如果这是真的,那听起来很贵。假设有100个事件。每个页面加载都会产生100 event.venue.get().name个请求。这意味着每天适度的10000页面浏览量会产生 10000 * 100 .get()请求。这听起来不错吗?

这是解决这个问题的最佳方法吗?如果没有,我可以考虑哪些选项?

2 个答案:

答案 0 :(得分:1)

首先,根据数据集中的场地总数,它们可能都很容易融入Memcache。因此,除非修改场地,否则无论页面查看次数多少,您都可以在不触及数据存储区的情况下使用数天。确保你也为你的场地使用Memcache。

其次,检索实体的更有效方法是批量请求。循环播放您的活动,创建一个您需要的所有场地的列表(顺便说一下,如果在同一场地发生多个事件,可能会小于事件数量 - 我看不到您的代码中的检查),然后为所有场地发出批量请求。

答案 1 :(得分:1)

以下是获取所有场地名称的Python代码:

venue_keys = set(event.venue for event in events)
venues = ndb.get_multi(venue_keys)
venue_name = {venue.key, venue.name for venue in venues}

然后,在您的模板中,您可以使用:

Event Venue: {{ venue_name.get(event.venue, 'No venue') }}