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

asc*_*d00 5 google-app-engine python-2.7 google-cloud-datastore

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

qry = MyModel.query(MyModel.title == 'title')
Run Code Online (Sandbox Code Playgroud)

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

使用'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)
Run Code Online (Sandbox Code Playgroud)

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

Gui*_*sum 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)
Run Code Online (Sandbox Code Playgroud)

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

        q = q.filter(MyModel._properties[kw] == v)
Run Code Online (Sandbox Code Playgroud)

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

        q = q.filter(getattr(MyModel, kw) == v)
Run Code Online (Sandbox Code Playgroud)

区别在于getattr()使用属性的"Python"名称,而_properties由属性的"数据存储"名称索引.这些仅在声明属性时才有所不同

class MyModel(ndb.Model):
  foo = StringProperty('bar')
Run Code Online (Sandbox Code Playgroud)

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