基本上,我想一次更新约10,000个实体-为每个实体添加新的属性和值。
提供此类:
Post(ndb.Model):
title = ndb.StringProperty()
created_date = ndb.DateTimeProperty()
我想运行某种操作,以便在我现有的created_date_string
实体中创建这个新的Post
属性,并使用日期的字符串版本占用该字段。
Post(ndb.Model):
title = ndb.StringProperty()
created_date = ndb.DateTimeProperty()
created_date_string = ndb.StringProperty(required=True)
我该如何处理?
我最好的猜测是使用任务队列来更新每个实体。我们将排队10,000个任务。有更好的方法吗?
答案 0 :(得分:3)
您可以在单个任务中执行此操作,该任务将遍历实体以更新它们。您将需要批处理您的收益和认沽权,以使其效率更高。任务最多需要运行10分钟,我敢打赌这将花费不到一分钟的时间。
确定要使用此新属性吗?您可以这样做:
Post(ndb.Model):
title = ndb.StringProperty()
created_date = ndb.DateTimeProperty()
@property
def created_date_string(self):
return str(self.created_date)
更新:
我应该已经解释了令人困惑的术语。这里“财产”有两种完全不同的用法。我回答的属性是特定于Python的,与GAE无关。 Python的@property
使函数看起来像变量,因此可以执行x.created_date_string
而不是x.created_date_string()
您可以执行以下操作,而不是我上面写的内容:
Post(ndb.Model):
title = ndb.StringProperty()
created_date = ndb.DateTimeProperty()
def created_date_string(self):
return str(self.created_date)
基本上是一样的东西。
Python属性与GAE计算属性不同,GAE计算属性是数据存储区中的实际属性。您也可以使用它,但是为什么不需要存储冗余数据。
答案 1 :(得分:1)
您正在将 created_date 属性的 String 版本存储在 created_date_string 中。为此,我可以想到两个用例。
仅在服务器上使用 created_date_string :如果仅在服务器端使用此属性,则无需存储它,因为它变得多余了,可以通过实例方法进行计算用于模型课程。
在API响应中发送 created_date_string :如果您通过API发送此属性并在客户端(网络/应用等)上使用它。最好的选择是使用Google App Engine的 ComputedProperty ,如下所示
created_date_string = ndb.ComputedProperty(lambda self:str(self.created_date))
这样,您的 created_date_string 属性将始终与 created_date 保持一致,并将自动创建并存储在DataStore中。
您可以找到有关ComputedProperty here
的更多信息回到关于如何更新10,000个实体的原始问题。由于这是一项工作,因此我建议使用延期。它还使用任务队列,但是相对易于使用。如定义中所述:
通过deferred库,您可以通过暴露一个简单的函数deferred.defer()
来绕过设置专用任务处理程序以及对参数进行序列化和反序列化的所有工作。您可以找到文档Here。给出的示例本身就是您要执行的批处理的代名词。
这就是我要怎么做。
编写专用的处理程序(例如: / runbatchupdate ),该处理程序将使用延迟的
从外部点击处理程序,或在cron.yaml中输入一个内容以运行该处理程序。
如果您需要示例代码,请在下面评论,我将为您编写一个示例处理程序。希望这会有所帮助