如何在Python中为Google App Engine过滤查询的键?
我有一个 query
,可以很顺利地在上面使用 filters
。这个方法没有问题,效果很好:
query.filter('foo =', 'bar')
但是,如果我想根据 key
或一组 key
来过滤我的查询呢?
我把它们当作 Key()
属性或者 string
来处理,但尝试了下面的方式后,发现并不奏效:
query.filter('key =', 'some_key') #no success
query.filter('key IN', ['key1', 'key2']) #no success
4 个回答
1
你可以通过下面这样的GQL查询来筛选数据:
result = db.GqlQuery('select * from Model where __key__ IN :1', [db.Key.from_path('Model', 'Key1'), db.Key.from_path('Model', 'Key2')]).fetch(2)
或者
result = Model.get([db.Key.from_path('Model', 'Key1'), db.Key.from_path('ProModelduct', 'Key2')])
1
你不能根据一个键来过滤。 哎呀,我之前说错了。其实,如果你设置了索引,你可以同时根据一个键和其他属性来过滤。它的样子是这样的:
key = db.Key.from_path('MyModel', 'keyname')
MyModel.all().filter("__key__ =", key).filter('foo = ', 'bar')
你还可以通过键、键的ID或者键的名称来查找多个模型,使用的是get
系列的方法。
# if you have the key already, or can construct it from its path
models = MyModel.get(Key.from_path(...), ...)
# if you have keys with names
models = MyModel.get_by_key_name('asdf', 'xyz', ...)
# if you have keys with IDs
models = MyModel.get_by_id(123, 456, ...)
这样你可以获取很多实体。我不知道具体的限制。如果有任何一个键不存在,你会在那个实体的列表中看到None
。
如果你需要根据某个属性和键同时进行过滤,你需要分两步来做。要么先根据键获取数据,然后检查属性,要么先根据属性查询,再验证键。
下面是一个在获取后进行过滤的例子。注意,你不需要使用查询类的filter
方法,而是直接对列表进行过滤。
models = MyModels.get_by_key_name('asdf', ...)
filtered = itertools.ifilter(lambda x: x.foo == 'bar', models)
3
虽然可以通过关键字进行筛选——参考@dplouffe的回答——但这样做并不是个好主意。'IN' 语句会对每个关键字执行一次查询,这样你就会进行和关键字数量一样多的查询,这种方法效率特别低。
更好的做法是使用批量获取操作,正如@Luke所提到的,然后在你的代码中把不需要的元素从列表中筛选掉。