【问题标题】:Google App Engine NDB Queries and exceeding memoryGoogle App Engine NDB 查询和超出内存
【发布时间】:2013-08-17 03:46:11
【问题描述】:

我有一个名为“Obj”的 Google App Engine 数据存储区,它在生产中拥有近 50 万个实体。我正在尝试仅查询 50 个 Obj 实体,但即使我将 limit 参数设置为 50,查询最终也会引发错误“超出软私有内存限制”。

这与在查询中使用 ndb.GenericProperty 有关吗?作为日期时间类型的属性“trashed_date”通常不是 Obj 的属性。我还手动为状态和垃圾日期创建了正确的索引。 “trashed_date”是否应该始终是该模型的属性?

以下是我正在使用的代码,如果只查询 50 个不超过内存限制的实体,我该怎么办?

q = Obj.query(
    Obj.status == 1,
    ndb.GenericProperty('trashed_date') < expire_date
)
results = q.fetch(50)

【问题讨论】:

  • 我怀疑它与通用属性有什么关系。虽然如果 Obj 类没有rashed_date 属性,你为什么要查询它?您要检索的实体有多大。每次运行查询时都会出现错误还是随着时间的推移出现错误?
  • 它总是抛出错误。人们的想法是,很少有 Obj 将拥有“trashed_date”属性。每个实体不应很大,不超过 1K。
  • 您可能想要分析您的应用。见code.google.com/p/apptrace/wiki/UsingApptrace。顺便说一句,您确实意识到此查询将永远不会返回不具有rashed_date 属性的实体。
  • 是的,不获取不具有垃圾日期属性的实体非常好。
  • 这可能值得一试。将 'trashed_date' 作为 DatetimeProperty 添加到 Obj 模型中,然后执行查询 Obj.query().filter(Obj.status == 1,Obj.trashed_date &lt; expire_date) 只是为了排除针对 DateTime 使用 GenericProperty 出现问题的可能性。

标签: python google-app-engine python-2.7 app-engine-ndb


【解决方案1】:

请尝试使用 q.iter() 和一个计数器将其限制为 50。我在 fetch() 上遇到了类似的问题,并使用 iter() 修复了它。 GAE 现在非常强烈地建议不要使用 fetch。 YMMV。 HTH。 -史蒂夫

【讨论】:

  • 你有反对使用fetch的声明的参考吗?我以为我也读过,但在文档中没有找到任何内容。
  • Quote: “注意:您应该很少需要使用此方法[fetch];使用 run() 几乎总是更好。”注意:db 是 run(),ndb 是 iter()] 链接:developers.google.com/appengine/docs/python/datastore/…
  • 啊,谢谢。如果iter 具有相同的限制,似乎应该在 ndb 文档中提及。
  • Sean,iter() 是 db 的 run() 的 ndb 等价物,因此它也是上述 fetch() 的首选替代方法。在其他地方(我不想追踪),fetch 被描述为 run/iter 的包装器。我的猜测是,当您 fetch(50) 时,您可能会让底层代码为您简单地进行迭代,并接收 50 个实体的列表。如果这些实体具有相当大的属性,那么您将达到实例的软内存限制(就像我一样)。 Fetch 更容易,因为没有计数器开销,所以它的目的是为了轻量级的东西。 HTH。 -史蒂夫
  • itertools.islice 为 iter() 提供了一个很好的类似 fetch 的包装器。结果 = islice(query.iter(), offset, page_size + offset)
猜你喜欢
  • 1970-01-01
  • 2015-06-27
  • 1970-01-01
  • 2019-11-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-23
  • 1970-01-01
相关资源
最近更新 更多