SQLAlchemy ORM/Python:oneliner仅当搜索值不是None时才包含查询过滤器(inline'if')

2024-04-18 22:01:55 发布

您现在位置:Python中文网/ 问答频道 /正文

我能在Python中实现方法级的内联if吗?你知道吗

我们来看看这个(简化的)情况:

# DB-level 'or'
db.session.query(TableClass).filter(or_(TableClass.column_1 == value_1,
                                        TableClass.column_2 == value_2)).first()

# basic Python-level 'if'
if value_1:
    db.session.query...value_1
if value_2:
    db.session.query...value_2

与其像上面那样查询DB或添加额外的if语句,是否可以通过以下方式实现相同的内联

# desired inline Python 'if' at method level
db.session.query(TableClass).filter({
           if value_1 TableClass.column_1 == value_1 \
           else if value_2 TableClass.column_2 == value_2 else None
    }).first()

# ^-- or something similar at method level

或者,让SQLAlchemy筛选器的一部分仅在基础值存在时处于活动状态。你知道吗

这里的主要动机是避免对None值进行DB搜索。你知道吗

尝试将starred expressionif语句作为suggested进行内联组合:

session.query(Foo).filter((*[Foo.attr1==attr1, Foo.attr2==attr2] if attr2 else *[Foo.attr1==attr1]))

但是我在if得到SyntaxError: invalid syntax。你知道吗

更新

现在我使用this style将条件定义为可以附加在一起的独立变量:

query = session.query(Table)

conditions = []
if abc:
    conditions.append(Table.field1 == foo)
if def:
    conditions.append(Table.field2 == bar)

query = query.filter(or_(*conditions))

尽管我很欣赏pierrev在下面的回答,但我还是为星号表达式和or_(TableClass.column_1 == value_1, true() if value_1 is None else false())建议修正了语法。你知道吗


Tags: ordbiffoovaluesessioncolumnfilter
1条回答
网友
1楼 · 发布于 2024-04-18 22:01:55

您可以通过移动括号来消除语法错误:

session.query(Foo).filter(*([Foo.attr1==attr1, Foo.attr2==attr2] if attr2 else [Foo.attr1==attr1]))

否则,您可能会使用^{}^{}Sqlalchemy表达式获得所需的结果。你知道吗

比如:

db.session.query(TableClass).filter(
    or_(TableClass.column_1 == value_1, true() if value_1 is None else false()),
    or_(TableClass.column_2 == value_2, true() if value_2 is None else false())
).first()

但我觉得它比

query = db.session.query(TableClass)
if value_1:
    query = query.filter(TableClass.column_1 == value_1)
if value_2:
    query = query.filter(TableClass.column_2 == value_2)

相关问题 更多 >