NDB - 删除密钥列表的最有效方法

C6S*_*ver 2 google-app-engine python-2.7 app-engine-ndb google-cloud-datastore

我相信我需要使用,ndb.delete_multi但我很困惑如何使它适用于一组特定的键,以及它是否是最有效的方法.将Python 2.7与Google App Engine结合使用.

首先,我正在收集我要删除的密钥.我不想删除所有内容,只删除1小时或更长时间的条目.为此,我首先收集符合此标准的密钥列表.

cs = ChannelStore()
delMsgKeys = []
for x in cs.allMessages():
   current = datetime.datetime.now()
   recordTime = x.channelMessageCreated
   timeDiffSecs = (current - recordTime).total_seconds()
   timeDiff = (timeDiffSecs/60)/60
   if timeDiff >=1:
      delMsgKeys.append(x.key.id())
ndb.delete_multi(?????)
Run Code Online (Sandbox Code Playgroud)

cs.allMessages()的定义:

def allMessages(self):
        return ChannelStore.query().fetch()
Run Code Online (Sandbox Code Playgroud)

首先,这总体上是最有效的方法吗?其次,如何使用我用ndb.delete_multi语句创建的密钥列表?

---更新----

ndb.delete_multi的问题与我传递的密钥有关.在我上面发布的代码中,密钥应该存储如下:

delMsgKeys.append(x.key)
Run Code Online (Sandbox Code Playgroud)

用上面的ndb.delete_multi工作.

use*_*197 6

根据NDB文档,您只需传入一个键列表ndb.delete_multi,因此根据您的代码,这应该可以工作:

ndb.delete_multi(delMsgKeys)
Run Code Online (Sandbox Code Playgroud)

不过,我不确定在一次ndb.delete_multi()通话中可以传递的键数是多少.

对于此查询:

ChannelStore.query().fetch()
Run Code Online (Sandbox Code Playgroud)

通过添加auto_now = True(此处提供更多文档),可以在创建/更新实体时添加实体属性以存储时间戳.然后使用该timestamp属性,您可以查询以下内容:

sixty_mins_ago = datetime.datetime.now()- datetime.timedelta(minutes = 60)
qry = ChannelStore.query()
list_of_keys = qry.filter(ChannelStore.timestamp < sixty_mins_ago).fetch(keys_only = True)
Run Code Online (Sandbox Code Playgroud)

由于您不需要实体,因此keys_only获取将更便宜.当然这段代码假设你的ChannelStore模型有一个timestamp属性,所以你的模型必须是这样的:

class ChannelStore(ndb.model):
    #other properties go here
    timestamp = ndb.DateTimeProperty(auto_now = True)
Run Code Online (Sandbox Code Playgroud)

总而言之,像这样的东西可能适用于上面的代码块:

from models import ChannelStore
from google.appengine.ext import ndb
from datetime import datetime, timedelta
# other imports

def delete_old_entities():
    sixty_mins_ago = datetime.now() - timedelta(minutes = 60)
    qry = ChannelStore.query()
    qry = qry.filter(ChannelStore.timestamp < sixty_mins_ago)
    list_of_keys = qry.fetch(keys_only = True)
    ndb.delete_multi(list_of_keys)
Run Code Online (Sandbox Code Playgroud)

如果您必须删除大量密钥并且在ndb.delete_multi调用时遇到某种API限制,您可以将delete_old_entities()方法更改为以下内容:

def delete_old_entities():
    sixty_mins_ago = datetime.datetime.now() - datetime.timedelta(minutes = 60)
    qry = ChannelStore.query()
    qry = qry.filter(ChannelStore.timestamp < sixty_mins_ago)
    list_of_keys = qry.fetch(keys_only = True)

    while list_of_keys:
        # delete 100 at a time
        ndb.delete_multi(list_of_keys[:100])
        list_of_keys = list_of_keys[100:]
Run Code Online (Sandbox Code Playgroud)