Sqlalchemy:使用多个filter() - 调用生成OR子句

时间:2010-09-01 12:41:40

标签: sqlalchemy

我是sqlalchemy的新手,可以使用一些帮助。 我正在尝试编写一个小应用程序,我必须动态更改select语句。我执行s = select([files]),然后按s = s.where(files.c.createtime.between(val1, val2))添加过滤器。 这很好用,但只能使用AND-conjunction。 因此,当我希望所有条目都包含createtime (between 1.1.2009 and 1.2.2009) OR createtime == 5.2.2009时,我遇到的问题是我不知道如何使用不同的过滤器调用来实现这一点。由于程序逻辑,无法使用s= s.where(_or(files.c.createtime.between(val1, val2), files.c.createtime == DateTime('2009-02-01')))

提前致谢, 克里斯托夫

2 个答案:

答案 0 :(得分:26)

您可以从列表中动态构建或约束:

clauses = []
if cond1:
    clauses.append(files.c.createtime.between(val1, val2))
if cond2:
    clauses.append(files.c.createtime == DateTime('2009-02-01'))
if clauses:
    s = s.where(or_(*clauses))

答案 1 :(得分:2)

如果您愿意通过在_whereclause对象上使用未记录的Select属性来“欺骗”,则可以通过每次基于以下内容构建新查询来逐步指定一系列OR术语上一个查询的where子句:

s = select([files]).where(literal(False)) # Start with an empty query.
s = select(s.froms).where(or_(s._whereclause,
        files.c.createtime.between(val1, val2)))
s = select(s.froms).where(or_(s._whereclause,
        files.c.createtime == datetime(2009, 2, 1)))

建立工会是另一种选择。这有点笨拙,但不依赖于未记录的属性:

s = select([files]).where(literal(False)) # Start with an empty query.
s = s.select().union(
        select([files]).where(files.c.createtime.between(val1, val2)))
s = s.select().union(
        select([files]).where(files.c.createtime == datetime(2009, 2, 1)))