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

使用PyODBC向SQL Server插入数据时偶发无异常但数据丢失问题求助

问题原因分析
  • 参数名拼写不一致(高概率):你SQL语句中的字段名为Condicion(无重音符号),但取值时用的是row.Condición(带重音符号),如果Excel读取生成的DataFrame列名没有重音符号,会导致该字段取值异常,触发静默插入失败,不会抛出可捕获的异常。
  • 数据截断/类型不匹配未触发报错:SQL Server默认配置下如果ANSI_WARNINGS参数为OFF,字符串超过字段长度、数值类型溢出等轻量错误不会触发异常,会直接静默丢弃不符合规则的行,你定义的Estado、Condicion都是定长nchar(10),如果Excel对应字段内容长度超过10,就会触发该问题。
  • DataFrame遍历的行异常:你使用df2.iterrows()遍历数据,该方法不会严格保留原始数据类型,如果Excel中的SAP、Aviso等整数字段读入时被转成浮点数、空值被识别为NaN,PyODBC可能会静默跳过该行插入,不会抛出异常。
  • 事务隐式回滚未被捕获:你仅在所有插入完成后执行一次cnxn.commit(),如果插入过程中出现数据库瞬时断连、死锁导致事务被SQL Server端主动回滚,可能出现客户端未收到异常提示、整批数据全部丢失的情况。
  • 动态表名拼接风险:你通过字符串格式化拼接表名,如果table_name存在特殊字符、或者和库中其他表重名(大小写不敏感的SQL Server实例下),可能出现数据插入到其他表的情况,看起来像是目标表数据丢失。
排查优化方案
# 建议替换单条插入为批量插入,同时增加执行结果校验
params = []
for index, row in df2.iterrows():
    # 提前校验字段取值,避免拼写错误
    params.append((
        row['SAP'], row['Equipo'], row['Estado'], 
        row['Aviso'], row['Fecha'], row['Condicion'], # 统一列名拼写
        row['Observaciones']
    ))
# 批量插入性能更高,也更容易排查整体执行结果
cursor.executemany("INSERT INTO {tab} (SAP,Equipo,Estado,Aviso,Fecha,Condicion,Observaciones) VALUES(?,?,?,?,?,?,?)".format(tab=table_name), params)
# 打印受影响行数,确认插入条数是否和DataFrame行数一致
print(f"本次插入影响行数:{cursor.rowcount}")
  • 插入前提前校验所有字段的长度、类型是否和SQL表定义匹配,过滤不符合规则的数据。
  • 开启SQL Server的ANSI_WARNINGS ON配置,确保数据异常时能抛出可捕获的错误。
  • 每次提交事务前后检查数据库连接状态,避免断连导致的提交失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 19:27:04