Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/google-app-engine/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google app engine 从Google App Engine NDB删除大量实体_Google App Engine_Google Cloud Datastore_App Engine Ndb - Fatal编程技术网

Google app engine 从Google App Engine NDB删除大量实体

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

之前的人在我们的谷歌应用程序引擎中制造了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(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
where
is\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秒内完成的批量大小工作即可。