如何在 SQLAlchemy 中编写嵌套连词(OR 和 AND 子句)?

Las*_*sma 4 python sql sqlalchemy

有人知道如何在 SQLAlchemy 中生成嵌套连接吗?

我有一些与此类似的 Python 代码:

import sqlalchemy as sa

a = sa.and_(mytable.col1 > 1, mytable.col2 < 3)
b = sa.and_(mytable.col1 < 1, mytable.col4 == None)
clause_args = [a, b] 
or_clauses = sa.or_(*clause_args)
session.query(mytable).filter(mytable.status.in_([1,2,3,4])).filter(or_clauses)
Run Code Online (Sandbox Code Playgroud)

请注意,这只是一些伪代码来演示我遇到的语法问题。不要过多分析查询逻辑。我只想找到一种如何在 AND 和 OR 块周围添加括号的方法。SQLAlchemy 生成的 SQL 类似于:

SELECT
     id, status, name, col1, col2, col3, col4
FROM mytable
WHERE
    status in (1,2,3,4)
AND (col1 > 1 
     AND col2 < 3
     OR col1 < 1
     AND col4 is NULL);
Run Code Online (Sandbox Code Playgroud)

注意,AND 条件在 OR 之间的逻辑 AND 块周围没有括号:

AND (col1 > 1 
     AND col2 < 3
     OR col1 < 1
     AND col4 is NULL);
Run Code Online (Sandbox Code Playgroud)

我想在带有 or_ 和 and_ 连词的过滤器中强制使用括号。我想将条件括起来,以便 SQL 输出如下所示:

SELECT
     id, status, name, col1, col2, col3, col4
FROM mytable
WHERE
    status in (1,2,3,4)
AND ((col1 > 1 
     AND col2 < 3)
     OR (col1 < 1
     AND col4 is NULL));
Run Code Online (Sandbox Code Playgroud)

有人可以建议如何实现这一目标吗?

谢谢!

小智 8

使用 self_group()。文档链接:self_group

该示例的解决方案看起来像

import sqlalchemy as sa

a = sa.and_(mytable.col1 > 1, mytable.col2 < 3).self_group()
b = sa.and_(mytable.col1 < 1, mytable.col4 == None).self_group()
clause_args = [a, b] 
or_clauses = sa.or_(*clause_args)
session.query(mytable).filter(mytable.status.in_([1,2,3,4])).filter(or_clauses)
Run Code Online (Sandbox Code Playgroud)

  • 您链接到的相同文档明确指出:[self_group() 的应用是自动的 - 最终用户代码永远不需要直接使用此方法](https://docs.sqlalchemy.org/en/13/core /sqlelement.html#sqlalchemy.sql.expression.ClauseElement.self_group) (3认同)

Ala*_*era 1

IIUC,不需要您正在寻找的括号,因为 AND 优先于 OR。