使用pyodbc向Access插入DataFrame时参数不匹配报错求助
问题解决:pyodbc插入Access数据库时参数不匹配错误
错误原因
你的SQL语句定义了21个参数占位符(?),但执行时传入的是整个DataFrame对象tDjango,这相当于只传了1个参数,和占位符数量不匹配,导致报错。循环遍历DataFrame时,你需要传入的是每一行的21个字段值,而非整个DataFrame。
修正方案
方案1:循环遍历每一行(适合小数据量)
使用iterrows()遍历DataFrame的每一行,将行数据转为列表传入execute:
for _, row in tDjango.iterrows(): cursor.execute( 'INSERT INTO TDjango ([Eid], [Eventtype], [Location], [Lat], [Lon], [Created], [TMCClosed], [FirstArrival(min)], [PatrolArrival(min)], [TowArrival(min)], [LanesCleared(min)], [RoadwayCleared(min)], [Camera], [DayofWeekOpened], [DayofWeekClosed], [sameDay], [confirmClosed], [confirmFirstAr], [confirmPtrl], [confirmTow], [confirmLnClear]) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', row.values.tolist() ) conn.commit()
- 注意:
iterrows()返回(索引, 行数据),用_忽略索引;row.values.tolist()会把当前行的所有字段值转为列表,刚好匹配21个占位符。 - 给带特殊字符(比如括号)的字段名加上方括号
[],避免Access解析语法错误。
方案2:批量插入(高效,适合大数据量)
用executemany()一次性传入所有行数据,无需循环,性能更优:
cursor.executemany( 'INSERT INTO TDjango ([Eid], [Eventtype], [Location], [Lat], [Lon], [Created], [TMCClosed], [FirstArrival(min)], [PatrolArrival(min)], [TowArrival(min)], [LanesCleared(min)], [RoadwayCleared(min)], [Camera], [DayofWeekOpened], [DayofWeekClosed], [sameDay], [confirmClosed], [confirmFirstAr], [confirmPtrl], [confirmTow], [confirmLnClear]) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)', tDjango.values.tolist() ) conn.commit()
tDjango.values.tolist()会把整个DataFrame转为二维列表,每一个子列表对应一行的字段值,完美匹配占位符数量。
额外注意事项
- 确保DataFrame的列顺序和SQL语句中字段的顺序完全一致,否则会出现值与字段不匹配的问题。
- 检查所有字段的数据类型是否和Access表中定义的类型兼容(比如日期、数字类型)。
内容的提问来源于stack exchange,提问作者joshuah9
相关产品推荐
相关产品推荐

