NDB query().iter() of 1000<n<1500 entities is wigging out

NDB query().iter() of 1000<n<1500 entities is wigging out

我有一个脚本,使用 Remote API,遍历一些模型的所有实体。假设有两个模型,称为 FooModel 约有 200 个实体,BarModel 约有 1200 个实体。每个都有 15 StringPropertys.

for model in [FooModel, BarModel]:
    print 'Downloading {}'.format(model.__name__)
    new_items_iter = model.query().iter()
    new_items = [i.to_dict() for i in new_items_iter]
    print new_items

当我在我的控制台中 运行 时,它在打印 'Downloading BarModel' 后挂了一会儿。它一直挂起,直到我按下 ctrl+C,此时它会打印下载的项目列表。

在 Jenkins 工作中 运行 时,没有人按 ctrl+C,所以它只是连续 运行s(昨晚它 运行 6 小时前一些东西,大概是詹金斯,杀死了它)。数据存储 activity 日志显示数据存储在整个 6 小时内每秒进行 5.5 API 次调用,同时产生几美元的 GAE 使用费。

为什么会这样? ctrl+C 的奇怪行为是怎么回事?为什么迭代器没有完成?

这是一个已知问题,目前正在 Issue 12908 下的 Google App Engine public 问题跟踪器上进行跟踪。该问题已转发给工程团队,有关该问题的进展将在上述主题中进行讨论。如果这对您有影响,请给问题加注星标以接收更新。

简而言之,问题似乎与 remote_api 脚本有关。查询给定种类的实体时,如果指定 batch_size,则在获取 1001 + batch_size 实体时会挂起。这不会发生在 remote_api.

之外的生产环境中

可能的解决方法

使用 remote_api

可以使用 querieslimit 参数来限制每次脚本执行时获取的实体数量。这可能有点乏味,但可以简单地从另一个脚本重复执行该脚本,以达到基本相同的效果。

使用管理 URL

对于重复操作,构建一个仅供管理员访问的网站 UI 可能是值得的。这可以在 users 模块的帮助下完成,如图 here 所示。这对于一次性任务来说不太实用,但对于定期维护任务来说要稳健得多。由于这根本不使用 remote_api,因此不会遇到此错误。