【问题标题】:NDB query filtering by property (string)NDB 查询按属性过滤(字符串)
【发布时间】:2012-03-20 22:32:14
【问题描述】:

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

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

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

使用“旧”方式,我有一个字典,其中包含要查询的键和值并循环遍历键和值:

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 实现这一点?

【问题讨论】:

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


    【解决方案1】:

    如果它是 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)
    

    或者,如果您只想按名称查找现有属性(在您的模型子类中定义),您可以使用 _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。

    【讨论】:

    • 这允许动态属性。有没有办法允许动态运算符,例如 ?
    • 好的,我的问题的答案在这里:stackoverflow.com/questions/8766150/…。基本上,使用 ndb.query.FilterNode("name", "=", value) 来构造过滤器
    • 对不起,我不明白if not isinstance(vals, (list, tuple)): vals = (vals,)的目的。你能给我解释一下吗?
    【解决方案2】:

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

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

    【讨论】:

    • 我相信这不是 100% 正确的:NDB query objects are immutable。因此,代码中的最后一行应该是“q = q.filter(prop == value)”
    • 这不是我所需要的。我只有属性标签作为字符串。所以没有 MyModel.title 但只有 'title' 。有没有办法通过字符串获取模型属性?
    • @alex 哎呀,这是我不知何故错过的 db 的变化。我会修正我的答案。
    • @aschmid00 您可以使用getattr(MyModel, x) 来获取名为x 的属性。您从哪里获得这些过滤器参数?
    • 是的 getattr 是我需要的。我在模型类上有一个 search() 函数,不同的处理程序将它与不同的 kwargs 一起使用,因此我必须过滤的道具在请求之间有所不同
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-07
    • 1970-01-01
    • 1970-01-01
    • 2021-09-24
    • 2013-05-12
    相关资源
    最近更新 更多