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

SQLAlchemy操作MSSQL含触发器表报错,求可行解决方案

问题描述

使用SQLAlchemy连接MSSQL 2019数据库,目标表parts存在无法删除的insert/update触发器,执行插入代码时触发以下错误:

The target table 'parts' of the DML statement cannot have any enabled triggers if the statement contains an OUTPUT clause without INTO clause.DB-Lib error message 20018

插入代码如下:

engine_new = create_engine('mssql+pymssql://***:***@***/***', implicit_returning=False)
Session_new = sessionmaker(bind=engine_new)
session_new = Session_new()
metadata_new = MetaData()
metadata_new.reflect(bind=engine_new)

partsTable = metadata_new.tables['parts']

def addPart(dataArt, manId):
    # rowInsertStmt = insert(partsTable).values(
    rowInsertStmt = partsTable.insert().values(
                    part_kod = dataArt.get('kod'),                
                    part_description = dataArt.get('title'),
                    part_kod_supplier = dataArt.get('supplier'),
                    part_manufacturer = manId
                )

    session_new.execute(rowInsertStmt)
    session_new.commit()

注:dataArt为零件描述字典,manId为制造商ID。

解决方案

1. 强制SQLAlchemy不生成OUTPUT子句

你已经在创建引擎时添加了implicit_returning=False,但可能对反射后的表未完全生效,可尝试两种方式补全设置:

  • 在insert语句中显式禁用返回值:
    修改insert语句,追加.returning(None)强制不生成OUTPUT子句:
    rowInsertStmt = partsTable.insert().values(
        part_kod = dataArt.get('kod'),                
        part_description = dataArt.get('title'),
        part_kod_supplier = dataArt.get('supplier'),
        part_manufacturer = manId
    ).returning(None)
    
  • 给反射后的表单独设置属性:
    在获取反射表后,直接设置表的implicit_returning为False:
    metadata_new.reflect(bind=engine_new, tables=['parts'])
    partsTable = metadata_new.tables['parts']
    partsTable.implicit_returning = False
    

2. 改用原生SQL执行插入

如果上述方法仍无法解决,可直接使用原生SQL绕开SQLAlchemy的语句生成逻辑:

from sqlalchemy import text

def addPart(dataArt, manId):
    insert_sql = text("""
        INSERT INTO parts (part_kod, part_description, part_kod_supplier, part_manufacturer)
        VALUES (:kod, :title, :supplier, :man_id)
    """)
    session_new.execute(insert_sql, {
        'kod': dataArt.get('kod'),
        'title': dataArt.get('title'),
        'supplier': dataArt.get('supplier'),
        'man_id': manId
    })
    session_new.commit()

这种方式完全由你控制SQL语句,不会生成OUTPUT子句,可彻底规避触发器冲突问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 11:08:23