【问题标题】:How to write nested conjunctions (OR and AND clauses) in SQLAlchemy?如何在 SQLAlchemy 中编写嵌套连词(OR 和 AND 子句)?
【发布时间】:2014-09-22 23:57:14
【问题描述】:

有人知道如何在 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)

注意,这只是一些伪代码来演示我遇到的语法问题。 不要过多分析查询逻辑。我只想找到一种在 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);

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

AND (col1 > 1 
     AND col2 < 3
     OR col1 < 1
     AND col4 is NULL);

我想在带有 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));

有人可以建议如何实现吗?

谢谢!

【问题讨论】:

标签: python sql sqlalchemy


【解决方案1】:

使用 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)

【讨论】:

  • 根据我的经验,自组行为的应用不一致 - 例如,在 SQLAlchemy 1.3.16 上,我可以通过在 or_ 块中包装一系列 and_ 块来触发行为。通过self_group() 强制行为可以很好地断言条件,无论解析器将来如何调整自己的行为。轶事,但这个“自动”应用程序在停止自动时会导致许多非常微妙的查询错误。
  • @tombishop83 有更好的解决方案吗?
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2014-11-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多