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

使用Pandas读取Excel导入数据库时INT字段类型转换报错求助

解决pyodbc参数类型错误(numpy.int32)及日期导入问题

问题分析

报错pyodbc.ProgrammingError: ('Invalid parameter type. param-index=3 param-type=numpy.int32', 'HY105')核心原因是:pyodbc无法直接识别numpy的数值类型,第3个参数benefit_value通过astype(int)得到的是numpy.int32,而非Python原生int类型。同时日期字段的转换逻辑也存在语法问题。

修复方案

1. 修正整数类型转换

无需先转字符串再转int,直接将numpy数值转为Python原生int即可:

benefit_value = int(df.loc[i][3])

如果Excel中该列存在空值(NaN),需先处理空值避免报错:

benefit_value = int(df.loc[i][3]) if pd.notna(df.loc[i][3]) else 0

2. 修正日期类型转换

astype(datetime)写法错误,需用pd.to_datetime转换后,转为Python原生datetime对象:

load_date = pd.to_datetime(df.loc[i][8]).to_pydatetime()

若数据库字段是仅存日期的DATE类型,可转为date对象:

load_date = pd.to_datetime(df.loc[i][8]).date()

优化后的逐行插入代码

df = pd.read_excel(self.filename)
n_rows = df.shape[0]
for i in range(n_rows):
    row = df.iloc[i]  # 用iloc比loc更高效
    pdpd_id = row[0]
    benefit_line = row[1]
    benefit_desc = row[2]
    benefit_value = int(row[3]) if pd.notna(row[3]) else 0
    benefit_type = row[4]
    detail = row[5]
    network_ind = row[6]
    prod_type = row[7]
    load_date = pd.to_datetime(row[8]).to_pydatetime()
    self.ODBCManager.insert_product_benefits(pdpd_id, benefit_line, benefit_desc, benefit_value, benefit_type, detail, network_ind, prod_type, load_date)

更高效的批量插入建议

逐行插入效率极低,推荐用pandas.to_sql批量导入:

from sqlalchemy import create_engine

# 预处理数据类型
df['benefit_value'] = df.iloc[:,3].apply(lambda x: int(x) if pd.notna(x) else 0)
df['load_date'] = pd.to_datetime(df.iloc[:,8]).dt.to_pydatetime()

# 创建SQLAlchemy连接(兼容pyodbc)
engine = create_engine('mssql+pyodbc://用户名:密码@DSN名称')

# 批量插入,if_exists可选replace/append
df.to_sql('product_benefits', engine, if_exists='append', index=False, chunksize=1000)

注:需保证DataFrame列名与数据库表字段名对应,或通过columns参数指定映射关系。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 14:30:08