如何使用Python3将含空值的CSV数据插入Firebird 2.5.8数据库
核心错误原因及修复方案
你当前代码存在3个直接导致插入失败的问题:
- 占位符规则错误:pyodbc 库的位置参数占位符统一为
?,而非你使用的%s,该写法不符合pyodbc的传参规范,会直接触发SQL语法错误。 - 字段名引号误用:SQL语法中单引号仅用于包裹字符串类型的数值,你给字段名加单引号会被Firebird识别为字符串常量,而非表的字段名,直接导致SQL执行失败。如果字段名是SQL关键字需要转义,Firebird需使用双引号包裹字段名。
- 空值处理逻辑错误:CSV中的空单元格被
csv.reader读取后为空字符串,你强制对所有值执行str()转换后,空值依然是字符串格式的'',无法对应数据库的NULL值,遇到日期、数字类型的字段时,插入空字符串会直接触发类型不匹配报错。你需要把空的字段值替换为Python的None,pyodbc会自动将None转换为SQL标准的NULL值。
修正后的代码
import csv import pandas as pd import pyodbc # 保留你原有正常的数据库连接逻辑即可:conn = pyodbc.connect(你的连接参数) cursor = conn.cursor() # 原有测试查询逻辑可以保留 sql_query = pd.read_sql_query("select * from login", conn) with open('Cleaned1.csv', 'r', encoding='utf-8') as read_obj: csv_reader = csv.reader(read_obj) header = next(csv_reader) if header is not None: for row in csv_reader: # 批量处理每个字段:空值替换为None,非空值转字符串 processed_row = [None if not item else str(item) for item in row] # 字段名取消单引号,占位符统一替换为? cursor.execute(""" INSERT INTO VEHICALAVAILABILITY (DATE, NODATE, DATEVBO, ETC, RELEASEDATE, VEH_REG_NO, VEHTYPE, AREA, DEPOT, NONCOMPACTOR, DESCDEFT, COMMENTS, VENDOR, NOTIFICATION, STATUSDATE, STATUS, DOWNTIME, VEHSTAT, VEHTYPE2, ATVENDOR) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) """, processed_row) conn.commit() cursor.close() conn.close()
额外优化建议
如果你的CSV数据量较大,建议使用executemany批量插入,而非逐行插入,执行效率会高很多。
内容的提问来源于stack exchange,提问作者user5438246
相关产品推荐
相关产品推荐

