我正在尝试显示一个包含约 800 个实体的表格,并且在阻止它变得非常慢时遇到了问题。(就像慢了 15-20 秒。)我成功实现了 memcache,但是因为我为每个子实体引用了一个父模型,它仍然会导致每个 800 的 datastore_v3.Get 并且非常慢。
然后我实现了 Nick Johnson 的ReferenceProperty 预取,但无法解决以下错误:
[... snipped ...]
File "/Applications/GoogleAppEngineLauncher.app/Contents/Resources/GoogleAppEngine-default.bundle/Contents/Resources/google_appengine/lib/webapp2/webapp2.py", line 570, in dispatch
return method(*args, **kwargs)
File "/myurl/mypythoncode.py", line 67, in get
prefetch_refprops(entitylist, ChildModel.parent_program.name)
File "/myurl/mypythoncode.py", line 36, in prefetch_refprops
fields = [(entity, prop) for entity in entities for prop in props]
TypeError: 'NoneType' object is not iterable
楷模:
这是两个相关的模型:
class ParentModel(db.Model):
name = db.StringProperty()
# currently 109 of these
class ChildModel(db.Model):
name = db.StringProperty()
parent_program = db.ReferenceProperty(ParentModel)
website = db.StringProperty()
# currently 758 of these
Python代码:
在我的 Python 代码中,我使用了 Nick Johnson 的高效模型缓存和ReferenceProperty 预取技术。(我在下面包含了 ReferenceProperty 预取,但没有包含 memcaching 代码。)
class AllEntities(webapp2.RequestHandler):
def get(self):
entitylist = deserialize_entities(memcache.get("entitylist"))
entityref = prefetch_refprops(entitylist, ChildModel.parent_program.name)
if not entitylist:
entitylist = ChildModel.all().fetch(None)
entityref = prefetch_refprops(entitylist, ChildModel.parent_program.name)
memcache.set("entitylist", serialize_entities(entitylist))
context = {
'entitylist': entitylist,
}
self.response.out.write(template.render(context))
def prefetch_refprops(entities, *props):
fields = [(entity, prop) for entity in entities for prop in props]
ref_keys = [prop.get_value_for_datastore(x) for x, prop in fields]
ref_entities = dict((x.key(), x) for x in db.get(set(ref_keys)))
for (entity, prop), ref_key in zip(fields, ref_keys):
prop.__set__(entity, ref_entities[ref_key])
return entities
Jinja2 模板:
我的 Jinja2 模板引用了“entitylist”中的可迭代“条目”,还引用了 parent_program.name 和 parent_program.key().id()
{% for entry in entitylist %}
<tr>
<td><a href="{{ entry.website}}">{{ entry.website }}</a></td>
<td><a href="/urlcategory/view?entityid={{ entry.parent_program.key().id() }}">{{ entry.parent_program.name }}</td>
</tr>
{% endfor %}
我已经更换了这条线:
entityref = prefetch_refprops(entitylist, ChildModel.parent_program.name)
和
entityref = prefetch_refprops(entitylist, ChildModel.parent_program)
以及包括“.name”和“.key().id()”在内的其他变体。当我使用“.key().id()”时出现错误:
AttributeError: 'ReferenceProperty' object has no attribute 'key'
我错过了什么或搞砸了什么?我真的很感激任何帮助!