这是我的困境:我必须通过一个实体列表来检查是否有一些重复的属性 - 我使用的是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
语句,但我不确定如何按重复属性的长度过滤查询。
答案 0 :(得分:3)
你有多少个实体?如果你有超过100左右,从远程api查询是非常低效的(二次)。所以这可以解释它是挂起的。
你是对的,你不能写一个检测你正在寻找的条件的查询。
答案 1 :(得分:1)
代码示例在找到没有引用的第一个实体时返回(如果没有引用,则返回skipped
)但是它可能会留下一些没有任何引用的实体。我不知道这是不是你想要的。
如果只有少数引用值可能,例如['python','ruby','php'],我认为你可以像Model.query(Model.references.IN(['python', 'ruby', 'php'])))
一样进行Repeated Properties查询,区别对待该列表包含所有实体的列表,并迭代剩余的实体。 (我不太了解NDB,并且怀疑这将是一个很好的方法,但是期望它适用于某些数据集。)
答案 2 :(得分: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"