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

Python向MS SQL插入DataFrame遇HY105错误及异常求助

问题:API加载的DataFrame插入MS SQL失败,报错参数类型错误及字符串拼接错误

错误信息

  1. 插入操作触发的错误:

pyodbc.ProgrammingError: ('Invalid parameter type. param-index=1 param-type=method', 'HY105')

  1. 异常处理环节触发的错误:

TypeError: can only concatenate str (not "set") to str

代码

def insert(db_connect):
    try:
        cursor = db_connect.cursor()
        sql_query = cursor.execute("Select * from Dashboard")
        allrows = sql_query.fetchall()
        totalrows = len(allrows)
        if totalrows > 0:
            cursor.execute("Truncate table Dashboard")
            logging.info('Truncated table :  ' + today.strftime("%d-%m-%Y %H-%M"))     
        
        text_data = response.text        
        json_dict = json.loads(text_data)        
        df = pd.DataFrame.from_dict(json_dict["elements"])
        
        print(df.columns.to_list())     
        for index, row in df.iterrows():
            cursor.execute("INSERT INTO Dashboard (SKID,Item,IDate,Warehouse,Location,TDate,Stock,GRN,Lane,Company) values(?,?,?,?,?,?,?,?,?,?)", row.mnum, row.item, row.idat, row.cwar, row.loca, row.trdt, row.stks, row.cval, row.valu1_0, row.company)
        
        logging.info('Data inserted successfully :  ' + today.strftime("%d-%m-%Y %H-%M"))
        #os.getcwd()
        ArchiveFilePath = os.path.join(ROOT_DIR, 'Archive\Dashboard_'+ d1 +'.xlsx')
        column_names = ['Mnum', 'Item','Idat','Cwar', 'Loca', 'Trdt', 'Stks', 'Cval', 'Valu 1', 'Company']
        df.to_csv(ArchiveFilePath,index=False,header=column_names, columns=['mnum','item','idat', 'cwar','loca','trdt', 'stks', 'cval', 'valu1', 'company' ])
        logging.info('File Created Successfully :  ' + today.strftime("%d-%m-%Y %H-%M"))    
    except Exception as e:
        print('Could not insert to database')
        logging.info('Could not insert to database :  ' + {str(e)})

SQL表结构

Dashboard表字段信息:

  • SKID (nvarchar(50))
  • Item (nvarchar(50))
  • IDate (datetime)
  • Warehouse (nvarchar(50))
  • Location (nvarchar(50))
  • TDate (datetime)
  • Stock (float)
  • GRN (nvarchar(50))
  • Lane (nvarchar(50))
  • Company (nvarchar(50))

解决方案

1. 修复参数类型错误(pyodbc.ProgrammingError)

问题根源是cursor.execute的参数传递不符合要求:pyodbc要求参数以元组/列表形式传入,且逐行插入效率极低。推荐两种修复方式:

方案一(推荐:用pandas内置方法批量写入)

删除原循环插入代码,改用to_sql完成数据写入,同时自动替代truncate逻辑:

# 将DataFrame列名映射为SQL表字段名
df.rename(columns={
    'mnum': 'SKID',
    'item': 'Item',
    'idat': 'IDate',
    'cwar': 'Warehouse',
    'loca': 'Location',
    'trdt': 'TDate',
    'stks': 'Stock',
    'cval': 'GRN',
    'valu1_0': 'Lane',
    'company': 'Company'
}, inplace=True)

# if_exists='replace'会先删除原表再重建,等价于truncate+插入
df.to_sql('Dashboard', db_connect, if_exists='replace', index=False)

方案二(坚持逐行插入)

将参数打包成元组传递给cursor.execute:

cursor.execute(
    "INSERT INTO Dashboard (SKID,Item,IDate,Warehouse,Location,TDate,Stock,GRN,Lane,Company) values(?,?,?,?,?,?,?,?,?,?)",
    (row.mnum, row.item, row.idat, row.cwar, row.loca, row.trdt, row.stks, row.cval, row.valu1_0, row.company)
)

同时需确认row.xxx是DataFrame的列值,而非Series内置方法(避免列名与方法重名)。

2. 修复字符串拼接错误(TypeError)

异常处理中{str(e)}创建了集合,无法与字符串拼接,修改为:

# 直接拼接字符串
logging.info('Could not insert to database :  ' + str(e))
# 或用更简洁的f-string写法
logging.info(f'Could not insert to database :  {str(e)}')

其他潜在问题修复

  • 确保response、today、d1、ROOT_DIR变量在函数内可访问或作为参数传入;
  • 修正归档文件路径:用os.path.join正确拼接,且to_csv对应.csv后缀:
    ArchiveFilePath = os.path.join(ROOT_DIR, 'Archive', f'Dashboard_{d1}.csv')
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 09:13:23