我正在同步来自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 - 而不是两个带有完整的循环?
答案 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'))))
注意:我还更新了上面链接的问题。