Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 通过聚合RPC调用加速GAE Py中的模板_Python_Google App Engine_Django Templates - Fatal编程技术网

Python 通过聚合RPC调用加速GAE Py中的模板

Python 通过聚合RPC调用加速GAE Py中的模板,python,google-app-engine,django-templates,Python,Google App Engine,Django Templates,我的问题是: class City(Model): name = StringProperty() class Author(Model): name = StringProperty() city = ReferenceProperty(City) class Post(Model): author = ReferenceProperty(Author) content = StringProperty() 代码并不重要。。。这是django模板: {% for po

我的问题是:

class City(Model):
  name = StringProperty()

class Author(Model):
  name = StringProperty()
  city = ReferenceProperty(City)

class Post(Model):
  author = ReferenceProperty(Author)
  content = StringProperty()
代码并不重要。。。这是django模板:

{% for post in posts %}
<div>{{post.content}}</div>
<div>by {{post.author.name}} from {{post.author.city.name}}</div>
{% endfor %}
事实证明我们可以。。。两者都证明了这一点。如果
@prefetch
方法通过捕获请求的键来包装模板渲染,我们可以(至少一个深度级别)捕获请求的键,返回模拟对象,并对其执行批处理。可以对所有深度级别重复此操作,直到没有请求新的关键点。最终渲染可以截取get并从贴图返回对象

这将以透明且无需任何额外代码的方式将总共200个进入3。更不用说大大减少了对memcache的需求,并在无法使用memcache的情况下提供帮助


问题是我还不知道怎么做。在我开始尝试之前,还有其他人这样做过吗?还是有人想帮忙?或者你看到了计划中的巨大缺陷吗?

我也遇到过类似的情况。我没有使用ReferenceProperty,而是使用父/子关系,但基本上是一样的。我当前的解决方案并没有经过优化,但至少它对于包含200-1000个实体的报告和事物来说足够有效,每个实体都有几个后续的子实体,需要获取

您可以批量手动搜索数据,并根据需要进行设置

# Given the posts, fetches all the data the template will need
# with just 2 key-only loads from the datastore.
posts = get_the_posts()

author_keys = [Post.author.get_value_for_datastore(x) for x in posts]
authors = db.get(author_keys)

city_keys = [Author.city.get_value_for_datastore(x) for x in authors]
cities = db.get(city_keys)

for post, author, city in zip(posts, authors, cities):
  post.author = author
  author.city = city
现在,当您呈现模板时,将不会执行其他查询或获取。边缘很粗糙,但是没有我刚才描述的这个图案我就活不下去了

您也可以考虑验证您的实体没有一个是代码> NOT/CODE >,因为DB。GET()如果密钥不正确,将返回任何一个。不过,这只是基本数据验证。类似地,如果有超时,则需要重试db.get(),等等


(最后,我不认为memcache可以作为主要解决方案。也许可以作为加速数据存储调用的第二层,但如果memcache为空,则需要很好地工作。此外,memcache本身有几个配额,例如memcache调用和传输的总数据。过度使用memcache是杀死应用程序死机的一个好方法。)我也遇到过类似的情况。我没有使用ReferenceProperty,而是使用父/子关系,但基本上是一样的。我当前的解决方案并没有经过优化,但至少它对于包含200-1000个实体的报告和事物来说足够有效,每个实体都有几个后续的子实体,需要获取

您可以批量手动搜索数据,并根据需要进行设置

# Given the posts, fetches all the data the template will need
# with just 2 key-only loads from the datastore.
posts = get_the_posts()

author_keys = [Post.author.get_value_for_datastore(x) for x in posts]
authors = db.get(author_keys)

city_keys = [Author.city.get_value_for_datastore(x) for x in authors]
cities = db.get(city_keys)

for post, author, city in zip(posts, authors, cities):
  post.author = author
  author.city = city
现在,当您呈现模板时,将不会执行其他查询或获取。边缘很粗糙,但是没有我刚才描述的这个图案我就活不下去了

您也可以考虑验证您的实体没有一个是代码> NOT/CODE >,因为DB。GET()如果密钥不正确,将返回任何一个。不过,这只是基本数据验证。类似地,如果有超时,则需要重试db.get(),等等


(最后,我不认为memcache可以作为主要解决方案。也许可以作为加速数据存储调用的第二层,但如果memcache为空,则需要很好地工作。此外,memcache本身有几个配额,例如memcache调用和传输的总数据。过度使用memcache是杀死应用程序死机的一个好方法。)以下是一些预取的好例子


以下是一些预取的好例子


我在回答中遗漏了一些东西。。。您可能意识到,与Python代码相比,RPC调用的速度非常慢,并且它与您的配额相对应。IIRC数据存储按键抓取大约需要100毫秒,因此200次抓取需要20秒。实际上,您正在进行400次抓取(一次从帖子抓取到作者,一次从作者抓取到城市),这样将超时您的页面。。。实际上,我的页面可能只显示10条帖子,我正在录制40个电话。只需一秒钟多一点,在100秒内拨打该号码可能很容易超时。此外,时区>=GMT+5(我假设)的用户万岁!我终于可以在所有西方人回答之前回答了扑通一声。。。是的,我没有看到太多东半球的人在这里做出贡献。那太好了:)我在回答中遗漏了什么。。。您可能意识到,与Python代码相比,RPC调用的速度非常慢,并且它与您的配额相对应。IIRC数据存储按键抓取大约需要100毫秒,因此200次抓取需要20秒。实际上,您正在进行400次抓取(一次从帖子抓取到作者,一次从作者抓取到城市),这样将超时您的页面。。。实际上,我的页面可能只显示10条帖子,我正在录制40个电话。只需一秒钟多一点,在100秒内拨打该号码可能很容易超时。此外,时区>=GMT+5(我假设)的用户万岁!我终于可以在所有西方人回答之前回答了扑通一声。。。是的,我没有看到太多东半球的人在这里做出贡献。那太好了:)第二个代码块非常有用。。。我没有想到zip会这样使用。。但第一块实际上是sdk的内置功能。。。引用在解析一次之后就已经被缓存了,所以根本不需要那个代码。你是对的。我的代码是从没有使用ReferenceProperty的类似情况复制的。通过一些后门来填充属性,而不仅仅是清除
.city
属性,这将是一件好事。但我相信在紧要关头这会管用的。嗯。。我正在读SDK中的google/appengine/ext/db/_init__.py中的代码。看起来一个简单的赋值可以很好地工作,因为它将调用ReferenceProperty的_set__()方法。我将更新答案,使其更简短、更清晰。完成:)另外,我忘了提到,我在实际代码中使用了itertools.izip,因为我过去经常碰到内存错误。不过,一般来说可能没有必要。itertools版本更快吗?为什么会有区别呢?对我来说,Zip似乎是一个非常简单的算法