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

SQLAlchemy操作MSSQL原生SQL给WHERE IN传列表报错如何解决

问题根因

该报错由MSSQL的ODBC驱动特性导致:pyodbc不支持将元组/列表作为单个参数直接绑定,你之前看到的通用写法适配的是PostgreSQL、MySQL等支持数组参数的数据库驱动,无法直接在MSSQL环境生效。

适配MSSQL的解决方案

方案1:使用expanding参数(最推荐)

SQLAlchemy提供了expanding参数专门用于IN子句的列表参数绑定,会自动根据传入的列表长度生成对应数量的占位符,全程使用参数绑定避免注入风险,示例代码如下:

from sqlalchemy import text, bindparam

id_list = [1, 2, 3]
query = text("select * from table where col in :id").bindparams(
    bindparam("id", expanding=True)
)
# 直接传列表即可,不需要转元组
conn.execute(query, {"id": id_list})

方案2:手动构造动态占位符

如果是较老版本的SQLAlchemy不支持expanding参数,可以手动生成和列表长度匹配的参数占位符,示例代码如下:

id_list = [1, 2, 3]
# 生成独立参数名
param_keys = [f"id_{idx}" for idx in range(len(id_list))]
# 拼接IN子句占位符
in_clause = ", ".join([f":{key}" for key in param_keys])
query = text(f"select * from table where col in ({in_clause})")
# 构造参数字典
params = {param_keys[idx]: id_val for idx, id_val in enumerate(id_list)}
conn.execute(query, params)

注意:不要直接把ID值拼接进SQL字符串,必须通过参数绑定传递,避免SQL注入风险

方案3:JSON解析适配长列表

如果IN子句的列表长度非常大(超过占位符数量限制),且使用的是SQL Server 2016及以上版本,可以通过JSON参数解析实现:

import json
from sqlalchemy import text

id_list = [1, 2, 3]
query = text("""
select * from table 
where col in (select cast(value as int) from OPENJSON(:id_json))
""")
# 将列表转成JSON字符串传入
conn.execute(query, {"id_json": json.dumps(id_list)})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 09:06:04