1

这是我的困境:我必须遍历一个实体列表,检查某些重复的属性——我正在使用 NDB——是否为空。如果是,那么我给它赋值,然后put(). 否则我跳过实体。我正在尝试在谷歌应用引擎附带的远程登录 shell 中完成所有这些工作。

我已经尝试过迭代 Model.query(),执行条件,并写入值,但是当我开始编写时,进程被挂断了。当我最终 Ctrl-C 时,它会弹出一条错误消息,“assert response.set_status_size() == len(server_keys); AssertionError”。我假设这与它试图检索的实体的大小有关。有谁知道怎么回事?这是我当前的代码:

>>> for entity in Model.query():
...    if not len(entity.references):
...        entity.references = somevalue
...        continue
...    print 'skipped'

我只会过滤查询而不是使用if语句,但我不确定如何按重复属性的长度过滤查询。

4

3 回答 3

3

你有多少实体?如果你有超过 100 个左右,从远程 api 查询确实效率低下(二次方)。所以这可以解释它挂起。

你是对的,你不能编写一个查询来检测你正在寻找的条件。

于 2012-12-17T07:37:04.457 回答
1

我终于让它工作了!我曾经query.fetch_page分批获取查询,然后遍历每个批次并应用更改。

>>> more = True
>>> cursor = None
>>> while more:
...     batch, cursor, more = MyModel.query().fetch_page(50, start_cursor=cursor)
...     for entity in batch:
...          if not len(entity.references):
...               entity.references = somevalue
...               entity.put()
...     print "finished batch"
于 2012-12-17T15:46:15.523 回答
1

代码示例在找到第一个没有引用的实体时返回(skipped如果没有引用则打印),但它可能会留下一些没有任何引用的实体。我不知道这是否是你的意图。

如果只有几个引用值是可能的,例如 ['python', 'ruby', 'php'],我认为您可以执行重复属性查询,例如Model.query(Model.references.IN(['python', 'ruby', 'php']))),将该列表与所有实体列表的差异,以及迭代剩余的实体。(我不太了解 NDB,并且怀疑这通常是一个好方法,但希望它对某些数据集可以正常工作。)

于 2012-12-17T01:08:54.550 回答