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

SQLAlchemy批量插入MS SQL Server时用OUTPUT无法获取全部插入ID的问题

问题原因

你当前的代码调用conn.execute(stmt, data)传入多组参数时,SQLAlchemy底层会调用ODBC的executemany接口,相当于分两次执行单条INSERT语句,每次插入一行数据。而SQL Server的ODBC驱动在默认executemany模式下,只会保留最后一次执行的结果集,因此你只能拿到最后一行插入数据的id。
你直接在数据库中执行的是单条INSERT携带两组VALUES的写法,仅执行一次,所以可以返回所有插入行的id,二者实际执行逻辑并不一致。

解决方案

方案1:开启SQLAlchemy批量VALUES合并(推荐,代码改动最小)

如果你使用的是SQLAlchemy 1.4及以上版本,只需要在创建数据库引擎时添加executemany_mode="values"参数,SQLAlchemy会自动把多组参数合并成单条INSERT的多VALUES语句,和你手写的原生SQL逻辑完全一致:

from sqlalchemy import create_engine
# 核心是添加 executemany_mode="values" 配置
engine = create_engine("mssql+pyodbc://你的数据库连接串", executemany_mode="values")

修改引擎配置后,你原有业务执行代码无需任何调整,就能正常获取所有插入行的id。

方案2:手动构造多VALUES的SQL语句

如果你的SQLAlchemy版本低于1.4,不支持executemany_mode参数,可以手动拼接占位符生成对应结构的SQL语句再执行:

try:
    data = [
         {'id': 1, 'fname':'Test1', 'lname':'rec1', 'dob':'05/05/2000'}
        ,{'id': 2, 'fname': 'Test2', 'lname': 'rec2', 'dob':'05/05/2001'}
    ]
    # 动态生成对应数量的VALUES占位符
    values_placeholders = ", ".join([f"(:id_{i}, :fname_{i}, :lname_{i}, :dob_{i})" for i in range(len(data))])
    sql = f"""
    INSERT INTO dbo.emp (id, fname, lname, dob)
    OUTPUT inserted.id
    VALUES {values_placeholders}
    """
    # 把批量参数打平成单组字典
    params = {}
    for idx, row in enumerate(data):
        params[f"id_{idx}"] = row["id"]
        params[f"fname_{idx}"] = row["fname"]
        params[f"lname_{idx}"] = row["lname"]
        params[f"dob_{idx}"] = row["dob"]

    stmt = text(sql)
    result = conn.execute(stmt, params)
    for id in result:
        print(id)

    conn.commit()
except exc.IntegrityError as e:
    print('Code3 - Integrity error raised',  e)
    conn.rollback()
except exc.SQLAlchemyError as e:
    print('Code3 - Something else went wrong', e)
    conn.rollback()

注意:SQL Server默认限制单条INSERT语句最多携带1000个VALUES项,如果你单次插入的行数超过1000,建议把数据拆成多批,每批不超过1000行分别执行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 01:06:05