Google App Engine - NDB - 反转 IN(列表)的最佳方式

Google App Engine - NDB - best way of inversing the IN(list)

我正在从 NDB 同步数据。

如何最好地查询所有元素,不包括所有已找到元素的列表 - 基本上反转 IN(list) 操作。

伪例子:

found = []
for ele in getElementList():
  ndb_data = ndb.get(ele)
  if ndb_data.is_same_as(ele):
    update(ele)
    found.append(ndb_data.key)
  else:
    delte(ele)
for ele in remaining(found): 
  create(ele)

def remaining(found_list):
  all = Element.query().fetch()
  do_not_want = Element.query(Element.key.IN(found_list)).fetch()
  for ele in all: 
    if ele in do_not_want:
       all.remove(ele)
  return all

换句话说,函数 remaining(found_list) 是否可以仅通过一次获取而不是两次完整循环来创建?

通过构建一系列 'x!=y AND x!=z' ndb 过滤器,我们可以模拟一个 'NOT IN' 查询:例如 (1):

checkList = ['cookieAck', 'newkey', 'tempCelsius']
query = UserSetting.query(Setting.name!=checkList[0])
for check in checkList[1:]:
  query = query.filter(ndb.AND(UserSetting.name!=check))

settings = query.fetch()

实际上这类似于以下手动构造的查询 (2):

  query = UserSetting.query(ndb.AND(ndb.AND(UserSetting.name!='cookieAck', UserSetting.name != 'newkey'), UserSetting.name != 'tempCelsius'))

请注意,只需执行以下操作也可以 (3):

query = UserSetting.query(UserSetting.name!='cookieAck', UserSetting.name != 'newkey', UserSetting.name != 'tempCelsius')

结果查询:

Query(kind='UserSetting', filters=OR(AND(FilterNode('name', '<', 'cookieAck'), FilterNode('name', '<', 'newkey'), FilterNode('name', '<', 'tempCelsius')), AND(FilterNode('name', '<', 'cookieAck'), FilterNode('name', '<', 'newkey'), FilterNode('name', '>', 'tempCelsius')), AND(FilterNode('name', '<', 'cookieAck'), FilterNode('name', '>', 'newkey'), FilterNode('name', '<', 'tempCelsius')), AND(FilterNode('name', '<', 'cookieAck'), FilterNode('name', '>', 'newkey'), FilterNode('name', '>', 'tempCelsius')), AND(FilterNode('name', '>', 'cookieAck'), FilterNode('name', '<', 'newkey'), FilterNode('name', '<', 'tempCelsius')), AND(FilterNode('name', '>', 'cookieAck'), FilterNode('name', '<', 'newkey'), FilterNode('name', '>', 'tempCelsius')), AND(FilterNode('name', '>', 'cookieAck'), FilterNode('name', '>', 'newkey'), FilterNode('name', '<', 'tempCelsius')), AND(FilterNode('name', '>', 'cookieAck'), FilterNode('name', '>', 'newkey'), FilterNode('name', '>', 'tempCelsius'))))

注意:我还更新了上面链接的问题。