python-2.7 - NDB - 删除键列表的最有效方法

标签 python-2.7 google-app-engine google-cloud-datastore app-engine-ndb

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

首先,我正在收集要删除的 key 。我不想删除所有内容,只删除 1 小时或更长时间的条目。为此,我首先收集满足此条件的 key 列表。

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(?????)

cs.allMessages() 的定义:

def allMessages(self):
        return ChannelStore.query().fetch()

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

---更新----

ndb.delete_multi 的问题与我传递给它的键有关。在我上面发布的代码中, key 应该按如下方式存储:

delMsgKeys.append(x.key)

有了上面的 ndb.delete_multi 作品。

最佳答案

根据 NDB documentation ,您只需将键列表传递给 ndb.delete_multi,因此根据您的代码,这应该可行:

ndb.delete_multi(delMsgKeys)

不过,我不确定您可以在单个 ndb.delete_multi() 调用中传递的键数限制是多少。

对于这个查询:

ChannelStore.query().fetch()

您可以在创建/更新实体时通过添加 auto_now = True ( more documentation here ) 添加实体属性来存储时间戳。然后使用 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)

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

class ChannelStore(ndb.model):
    #other properties go here
    timestamp = ndb.DateTimeProperty(auto_now = True)

将它们放在一起,类似这样的东西可以用于您上面的代码块:

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)

如果您必须删除大量 key 并且使用 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:]

关于python-2.7 - NDB - 删除键列表的最有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25172491/

相关文章:

python - 如何使用 ElementTree 正确解析 utf-8 xml?

php72 动态 url 路由与前端 Controller 通过入口点标准不起作用 Google App Engine [GAE]

python - 从登录我的 GAE 应用程序的用户发送电子邮件

python - python简单加法程序

python - 循环进口困惑

google-app-engine - 数据存储读/写操作

unit-testing - Google App Engine 数据存储 - 测试查询失败

google-app-engine - 在 AppEngine 查询中使用 "ANCESTOR IN <list>"

python - Google Appengine 数据存储区何时可以返回过时数据?

python - 在 python 中从全局范围解析变量