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

时间:2015-08-19 15:58:33

标签: python google-app-engine google-cloud-datastore fetch app-engine-ndb

我正在同步来自NDB的数据。

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

伪示例:

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

换句话说,剩下的函数(found_list)是否只需要一个单一的setchl - 而不是两个带有完整的循环?

1 个答案:

答案 0 :(得分:1)

通过构造一系列'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'))))

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