3

我必须向现有的 NDB 类添加一个新属性:

class AppList(ndb.Model):
    ...
    ignore = ndb.BooleanProperty(default=False) # new property

然后我会像下面这样使用它:

entries = AppList.query()
entries = entries.filter(AppList.counter > 5)
entries = entries.filter(AppList.ignore == False)
entries = entries.fetch()

我不能AppList.ignore != True用来捕获早期添加的记录(没有ignore属性),所以我必须为我的实体False中的所有记录分配。AppList最有效的方法是什么?目前,该实体包含大约 4'000 个条目。

更新。我决定使用以下丑陋的代码(没有设法应用cursors),它作为 cron 作业运行。但是我不是每次都更新相同的 100 条记录吗?

entities = AppList.query()
# entities = entities.filter(AppList.ignore != False)
entities = entities.fetch(100)
while entities:
    for entity in entities:
        entity.ignore = False
        entity.put()
    entities = AppList.query()
    # entities = entities.filter(AppList.ignore != False)
    entities = entities.fetch(100)
4

4 回答 4

3

不要忘记在这些情况下使用了一个 MapReduce 库。但我认为最好的方法是结合使用所有这些建议。

现在,您需要 get() 和 put() 4000 个实体,问题是如何降低此操作的“成本”。

我只是想知道你的bool(entity.ignore)回报是什么。如果missing属性返回 False,您可以考虑将其调整为 False 并推迟操作。如果你 put() 出于其他原因,由于默认参数,该属性ignore被写入。False因此,对于其余实体可以运行这样的脚本(通过 remote_api):

def iter_entities(cursor=None):
    entries = AppList.query()
    res, cur, more = entries.fetch_page(100, start_cursor=cursor)
    put_queue = [ent for ent in res if not hasattr(ent, 'ignore')]
    # put_queue = []
    # for ent in res:
    #    if not hasattr(ent, 'ignore'):
    #        put_queue.append(ent)
    ndb.put_multi(put_queue)
    if more:
        iter_entities(cur) # a taskqueue is better
于 2013-11-08T22:48:00.463 回答
2

您可以尝试使用 hasattr 检查记录是否具有忽略属性。

如果您只想为 AppList 实体中的所有记录分配 False,则只需更新架构(重新加载 models.py 文件),然后您应该能够将属性设置为 False。

可以在此处找到有关架构更新的更多信息。

编辑:回答您的评论:

if hasattr(entity, 'ignore'):
  #your code goes here
于 2013-11-07T20:44:54.110 回答
2

您更新的代码将仅更新前 100 个实体。尝试使用光标

https://developers.google.com/appengine/docs/python/ndb/queries#cursors

如果您不能使用游标,则使用偏移量并在每个循环上将偏移量增加 100 或通过 fetch() 获取所有条目一次(游标方法更好)

而不是将它们一一放置,而是使用 ndb.put_multi(list of entity to put)

这会比一张一张放的快

于 2013-11-08T12:11:31.163 回答
1

不部署新代码的最简单方法是使用远程 api 并执行查询以获取所有实体并将属性值设置为 false,然后 put() 它们。4000条记录不是很多。

实际上你甚至不需要显式设置值,如果当前没有值,它会在检索时设置为默认值。

于 2013-11-07T22:58:50.370 回答