使用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
相关产品推荐
相关产品推荐

