Google app engine 从Google App Engine NDB删除大量实体
之前的人在我们的谷歌应用程序引擎中制造了som问题。目前,该应用程序正在使用空值保存实体,但如果我们能够清除所有THES值会更好 以下是ndb.Modal:Google app engine 从Google App Engine NDB删除大量实体,google-app-engine,google-cloud-datastore,app-engine-ndb,Google App Engine,Google Cloud Datastore,App Engine Ndb,之前的人在我们的谷歌应用程序引擎中制造了som问题。目前,该应用程序正在使用空值保存实体,但如果我们能够清除所有THES值会更好 以下是ndb.Modal: class Day(ndb.Model): date = ndb.DateProperty(required=True, indexed=True) items = ndb.StringProperty(repeated=True, indexed=False) reason = ndb.StringProperty
class Day(ndb.Model):
date = ndb.DateProperty(required=True, indexed=True)
items = ndb.StringProperty(repeated=True, indexed=False)
reason = ndb.StringProperty(name="cancelled", indexed=False)
is_hole = ndb.ComputedProperty(lambda s: not bool(s.items or s.reason))
不知何故,我们需要删除所有天中为空的为真的
大约有400000个实体,服务器上应该删除大约2000000个实体
到目前为止的代码
我认为最好先计算一下我们应该使用以下代码删除多少实体:
count = Day.query(Day.is_hole != False).count(10000)
ndb.delete_multi([key for key in Day.query(Day.is_hole != False).fetch(10000, keys_only=True)])
这(限制为10000)大约需要5秒才能运行。如果没有限制,则会出现死线异常
对于删除,我尝试了以下代码:
count = Day.query(Day.is_hole != False).count(10000)
ndb.delete_multi([key for key in Day.query(Day.is_hole != False).fetch(10000, keys_only=True)])
这(有限制)大约需要30秒
问题
我怎样才能更快地删除所有Day
whereis\u hole!=错误
(我们正在使用Python)不,没有更快的方法来删除实体-截止日期是固定的
但也有一些技巧
若要使用,可以延长截止时间。若要将某些任务放入队列,可以在第一个任务(重复)之后生成下一个任务
另一个类似于任务队列的选项是,在删除某些坏记录后,将其重定向到正在删除的同一处理程序,同时删除最后一条记录。需要浏览器一直打开到最后
如果至少有一条不良记录:
删除一些记录(不超过30秒)
再次生成此任务或重定向到此处理程序(下一次调用将有30秒)
记住,如果没有更好的记录,它就有退出点。它将删除所有匹配的记录,而无需再次单击。最好的方法是使用MapReduce,它将在任务队列中运行,并且您还可以进行分片以并行工作。下面是python代码。如果您需要任何澄清,请告诉我
main.py
from mapreduce import base_handler
from mapreduce import mapreduce_pipeline
from mapreduce import operation as op
from mapreduce.input_readers import InputReader
from google.appengine.api import app_identity
def deleteEntity(entity):
yield op.db.Delete(entity)
class DeleteEntitiesPipeline(base_handler.PipelineBase):
def run(self):
bucket_name = (app_identity.get_default_gcs_bucket_name())
yield mapreduce_pipeline.MapPipeline(
"job_name",
"main.deleteEntity",
"mapreduce.input_readers.DatastoreInputReader",
params={
"entity_kind": 'models.Day',
"filters": [("is_hole", "=", True)],
"bucket_name": bucket_name
},
shards=5)
class StartDelete(webapp2.RequestHandler):
def get(self):
pipeline = DeleteEntitiesPipeline()
pipeline.start()
application = webapp2.WSGIApplication([
('/deleteentities', StartDelete),
], debug=True)
如果您不介意它运行更长时间,您可以通过远程api和基于您已有的游标来完成。这样,它可以运行任意长时间,只需确保每次往返都能以60秒内完成的批量大小工作即可。