You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为SQLAlchemy text()查询的IN子句传递值列表?

解决SQLAlchemy向SQL Server传递IN子句列表参数的报错问题

问题重现

尝试通过SQLAlchemy将列表作为参数传入IN子句,代码如下:

args = [112210104, 112012523]
raw_sql = "SELECT * FROM table WHERE id IN :values" 
query = sqlalchemy.text(raw_sql).bindparams(values=tuple(args))
cnxn_gw.engine.execute(query)

遇到错误:

DBAPIError: (pyodbc.Error) ('HY004', '[HY004] [Microsoft][ODBC SQL Server Driver]Invalid SQL data type (0) (SQLBindParameter)')
[SQL: SELECT * FROM table WHERE id IN ?]
[parameters: ((112210104, 112012523),)]

解决方案

方法1:使用expanding参数(推荐,SQLAlchemy 1.3+)

利用SQLAlchemy提供的bindparam并设置expanding=True,它会自动处理列表参数,将其展开为IN子句所需的多个占位符:

import sqlalchemy

args = [112210104, 112012523]
raw_sql = "SELECT * FROM table WHERE id IN :values" 
# 用bindparam指定expanding参数
query = sqlalchemy.text(raw_sql).bindparams(
    sqlalchemy.bindparam('values', expanding=True, value=args)
)
cnxn_gw.engine.execute(query)

方法2:动态生成占位符

如果使用的SQLAlchemy版本较低不支持expanding,可以根据列表长度动态生成对应数量的占位符,再直接传递列表参数:

import sqlalchemy

args = [112210104, 112012523]
# 根据列表长度生成N个占位符
placeholders = ', '.join(['?' for _ in args])
raw_sql = f"SELECT * FROM table WHERE id IN ({placeholders})"
query = sqlalchemy.text(raw_sql)
# 用*args将列表元素作为多个参数传递
cnxn_gw.engine.execute(query, *args)

原因说明

原代码将tuple作为单个参数传递给:values,但SQL Server的ODBC驱动无法识别这种复合数据类型作为IN子句的参数,因此抛出"Invalid SQL data type"错误。上述两种方法都是将列表元素拆分为独立的参数,符合SQL Server驱动的参数绑定要求。

内容的提问来源于stack exchange,提问作者cdlabs45

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 22:01:01