Python导入数据到Access遇pyodbc整数列HYC00错误解决方案咨询
Access写入整数列报错解决方案
你遇到的报错是Access ODBC驱动对numpy整数类型的兼容性问题,pandas默认导出的整数列是numpy.int64格式,Microsoft Access的ODBC驱动不支持该类型的参数绑定,所以抛出对应错误。无需将整数转浮点,可参考以下三种可行方案:
方案1:为to_sql方法明确指定字段类型映射
手动用SQLAlchemy的类型类声明每个列对应Access的字段类型,避免pandas自动推断类型出错,整数列统一用Integer类型即可,修改后的代码示例如下:
import pandas as pd import numpy as np import pyodbc from sqlalchemy import create_engine # 新增导入SQLAlchemy类型类 from sqlalchemy.types import Integer, String, Float, DateTime from io import BytesIO from urllib.request import urlopen from zipfile import ZipFile # 下载解压数据部分代码不变 zipurl = 'https://www.data.boem.gov/Well/Files/5010.zip' with urlopen(zipurl) as zipresp: with ZipFile(BytesIO(zipresp.read())) as zfile: zfile.extractall('/temp/leasedata') colspecs = [(0, 12), (13, 17), (18, 26), (27, 31), (31, 37), (39, 47), (47, 53), (57, 62), (62, 67), (67, 73), (84, 86), (86, 92), (104, 106), (106, 112), (112, 120), (120, 128), (131, 134), (134, 139), (140, 155), (156, 171), (172, 187), (188, 203), (203, 213)] df = pd.read_fwf('/temp/leasedata/5010.DAT', colspecs=colspecs, header=None) df.columns = ['API', 'WellName', 'Suffix', 'OprNo', 'BHFldName', 'SpudDate', 'BtmOCSLse', 'RKBElev', 'TotalMD', 'TVD', 'SurfArea', 'SurfBlock', 'BHArea', 'BHBlock', 'TDDate', 'StatusDate', 'StatusCode', 'WaterDepth', 'SurfLon', 'SurfLat', 'BHLon', 'BHLat', 'SurfOCSLse'] # 手动定义字段类型映射 dtype_map = { # 整数类字段指定为Integer类型 'RKBElev': Integer(), 'TotalMD': Integer(), 'TVD': Integer(), 'WaterDepth': Integer(), # 字符串类字段指定为String,长度根据实际数据调整,适配Access要求 'API': String(12), 'WellName': String(50), 'Suffix': String(10), 'OprNo': String(10), 'BHFldName': String(20), # 日期类字段指定为DateTime 'SpudDate': DateTime(), 'TDDate': DateTime(), 'StatusDate': DateTime(), # 经纬度等浮点类字段指定为Float 'SurfLon': Float(), 'SurfLat': Float(), 'BHLon': Float(), 'BHLat': Float() } conn = create_engine("access+pyodbc://@OOSA") # 写入时传入dtype参数,新增index=False避免写入多余的索引列 df.to_sql('borehole_temp_table', conn, if_exists='replace', index=False, dtype=dtype_map)
方案2:将numpy整数转换为Python原生整数类型
如果不想手动声明所有字段类型,只需要将整数列的numpy.int格式转为Python原生int,空值替换为None即可适配ODBC驱动要求:
# 填入所有需要保留整数类型的列名 int_cols = ['RKBElev', 'TotalMD', 'TVD', 'WaterDepth'] for col in int_cols: df[col] = df[col].apply(lambda x: int(x) if pd.notna(x) else None) # 后续写入逻辑不变 df.to_sql('borehole_temp_table', conn, if_exists='replace', index=False)
方案3:使用win32com替代ODBC操作Access
如果本地已安装Access软件,可使用pywin32库直接调用Access的COM接口写入数据,完全绕开ODBC驱动的兼容性问题,无需配置DSN。
内容的提问来源于stack exchange,提问作者Heather
相关产品推荐
相关产品推荐

