如何在Python中为Google App Engine过滤查询的键?

3 投票
4 回答
4578 浏览
提问于 2025-04-16 11:29

我有一个 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所提到的,然后在你的代码中把不需要的元素从列表中筛选掉。

撰写回答