【问题标题】:Peewee query based on columns known only at runtime基于仅在运行时已知的列的 Peewee 查询
【发布时间】:2017-05-08 22:19:07
【问题描述】:

我目前正在构建一个 SQL 查询(在 Python 中):

query = "SELECT * FROM Table WHERE (" + \
    " OR ".join([firstType+'=1' for firstType in firstTypes]) + \
    ") AND (" + \
    " OR ".join([secondType+'=1' for secondType in secondTypes]) + \
    ")"

给定两个列表 firstType=['B','F']secondType=['a','d'] 生成查询

SELECT * FROM Table WHERE ( ('B'=1 OR 'F'=1) AND ('a'=1 OR 'd'=1) )

我使用Table.raw(query) 执行。

我知道如何在 Peewee 中生成特定查询,例如:

Table.select().where( (Table.B=1 | Table.F=1) & (Table.a=1 | Table.d=1) )

但问题是我事先不知道这两个列表(即列)的内容。

如何基于仅在运行时才知道的(可能有很多)列动态构建 Peewee 查询?

【问题讨论】:

    标签: python sql orm peewee


    【解决方案1】:

    这很简单——您只需使用field = getattr(MyModel, 'field_name')field = MyModel._meta.fields['field_name']

    那么你大概会生成一个表达式列表:

    data = {'field_a': 1, 'field_b': 33, 'field_c': 'test'}
    clauses = []
    for key, value in data.items():
        field = MyModel._meta.fields[key]
        clauses.append(field == value)
    

    要将所有子句AND放在一起,你可以:

    import operator
    expr = reduce(operator.and_, clauses) # from itertools import reduce in Py3
    

    他们:

    import operator
    expr = reduce(operator.or_, clauses)
    

    最后一步是将其放入查询的where() 子句中。

    【讨论】:

    • 你永远不会给人留下深刻印象,@coleifer
    • 很高兴我的回答有帮助。
    • @coleifer,今天没有其他解决方案吗?无需访问“受保护”成员:) 这个工作完美,只是想知道是否出现了更优雅的东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-01
    相关资源
    最近更新 更多