NDB查询按属性过滤(字符串)

时间:2012-03-20 22:32:15

标签: google-app-engine google-cloud-datastore python-2.7

使用ndb和要在查询上使用过滤器的新查询类,您需要使用如下语法:

qry = MyModel.query(MyModel.title == 'title')

如何在不事先知道我必须查询哪些属性的情况下查询模型?

使用'old'方式我有一个字典,其中包含要查询的键和值以及循环键和值:

kwargs = {'title' : 'mytitle', 
          'age'   : 34 }

q = MyModel.all()

for kw, vals in kwargs.items():
    if not isinstance(vals, (list, tuple)):
        vals = (vals,)
    for v in vals:
        q.filter('%s =' % kw, v)

我怎样才能用ndb实现这个目标?

2 个答案:

答案 0 :(得分:13)

如果它是Expando模型,或者您不关心验证属性名称,则可以使用GenericProperty轻松完成此操作:

kwargs = {'title' : 'mytitle', 
          'age'   : 34 }

q = MyModel.query()

for kw, vals in kwargs.items():
    if not isinstance(vals, (list, tuple)):
        vals = (vals,)
    for v in vals:
        q = q.filter(ndb.GenericProperty(kw) == v)

或者,如果您只想按名称查找现有属性(在Model子类中定义),则可以使用_properties类属性,例如

        q = q.filter(MyModel._properties[kw] == v)

甚至使用getattr()从类中获取它:

        q = q.filter(getattr(MyModel, kw) == v)

不同之处在于getattr()使用属性的“Python”名称,而_properties由属性的“数据存储”名称索引。仅当使用类似

的声明声明属性时,这些才会有所不同
class MyModel(ndb.Model):
  foo = StringProperty('bar')

这里的Python名称是foo,但数据存储名称是bar。

答案 1 :(得分:0)

您仍然可以使用字典执行此操作 - 键只需要是模型属性而不是字符串,如下所示:

kwargs = {MyModel.title : 'mytitle', 
          MyModel.age   : 34 }
q = MyModel.query()
for prop, value in kwargs.items():
  q = q.filter(prop == value)