首页 > 解决方案 > SQLAlchemy Where 列列表中的值

问题描述

在将我的代码移动到 SQLAlchemy 之前,我有一个 MySQL 查询,它在多个列(例如 - )中查找一个值,WHERE 'value' in (col1, col2)当手动将查询提交到数据库时它可以正常工作。

上面的用例相对简单,但将来我可能想在两个以上的列上运行类似的查询,所以现在只想解决这个问题。

目前我已将我的查询转换为以下(有效),但我试图找到与上述类似的语法。

metadata = sqlalchemy.MetaData(mydb, reflect=True)
select_stmt = (tbl_pbp.select(
              ((tbl_pbp.c.home_team == team_abbreviation) | (tbl_pbp.c.away_team == team_abbreviation))
              & (tbl_pbp.c.is_corsi == True)))

当我尝试以下操作时,我收到一个语法错误,所以不确定这是否是in_我尝试使用的关键字的问题。

metadata = sqlalchemy.MetaData(mydb, reflect=True)
select_stmt = (tbl_pbp.select(
              (team_abbreviation in_(tbl_pbp.c.home_team, tbl_pbp.c.away_team)
              & (tbl_pbp.c.is_corsi == True)))

非常感谢任何帮助 - 谢谢!

标签: pythonmysqlsqlalchemy

解决方案


为了在SQL 表达式语言中将 Python 值作为 SQL 文字进行操作,它必须用literal(). 然后可以使用生成的构造来生成所需的IN子句:

literal(team_abbreviation).in_([tbl_pbp.c.home_team, tbl_pbp.c.away_team])

正如评论中所指出的,这相当于产生一堆与 结合的相等性检查OR。在这种情况下,唯一的参数in_()应该是一个合适的序列,例如一个列表。

请注意,in_这里是SQLAlchemy 构造的方法in,而不是 Python operator ,由于它如何处理 : 的返回值,它不能被重载以生成自定义构造__contains__():它隐式转换为 a bool

In [1]: class X:
   ...:     def __contains__(self, item):
   ...:         return 'nope'
   ...:     

In [2]: 1 in X()
Out[2]: True

推荐阅读