Python调用MySQL LOAD DATA INFILE导入CSV文件异常排查
问题场景
完成数据处理操作后,将两列数据以CSV格式存储为txt文件,result.txt文件内容如下:
id,avg 0,38.0 1,56.5 3,66.5 4,48.666666666666664
后续将该文件数据导入MySQL数据表时出现故障:直接执行对应.sql导入语句可成功存储数据,但通过Python执行相同查询语句时无法正常生效。
对应的Python代码如下:
. . . open('C:/ProgramData/MySQL/MySQL Server 8.0/Uploads/result.txt', 'w').write(res) print(res) try: with mysql.connector.connect( host="localhost", user='root', password='tt', database="dp", ) as connection: clear_table_query = "drop table if exists test_db.marks;" create_table_query = ''' create table test_db.marks ( id varchar(255) not null, avg varchar(255) not null, primary key (id) ); ''' # 删除表、重建表的逻辑可以正常运行 add_csv_query = "LOAD DATA INFILE 'C:/ProgramData/MySQL/MySQL Server 8.0/Uploads/result.txt' INTO TABLE marks FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY '\\n' IGNORE 1 LINES;" print(add_csv_query) # 打印的查询语句语法正确 with connection.cursor() as cursor: cursor.execute(clear_table_query) cursor.execute(create_table_query) cursor.execute(add_csv_query) cursor.execute("SELECT * FROM test_db.marks;") # 此处抛出Unread result found异常 except mysql.connector.Error as e: print(e) connection.close()
代码中删除旧表、重建新表的逻辑可正常运行,打印的LOAD DATA语句无语法错误,但执行导入后运行SELECT查询时会抛出Unread result found异常。
故障原因
这个报错是mysql-connector的默认机制导致的:LOAD DATA INFILE语句执行完成后,会返回一个记录导入行数、告警数等信息的结果集,连接器要求必须消费完上一条语句返回的所有结果,才能执行下一条语句。代码中执行完LOAD DATA后没有处理它返回的结果,直接执行SELECT语句,就会触发未读结果的报错。
另外代码里还存在两个潜在问题:
- 连接时指定的默认数据库是
dp,但LOAD DATA语句中写入的表名是marks没有带库名前缀,和建表、查询时用的test_db.marks不一致,容易触发表不存在的错误 - Windows环境下生成的文本文件默认换行符是
\r\n,当前LOAD DATA语句里指定的行终止符是\n,可能导致导入的数据末尾携带多余回车符
解决方法
- 方案1:手动消费结果集。在执行完会返回额外结果的语句后,调用
cursor.nextset()跳过当前返回的非目标结果,再执行后续语句即可。 - 方案2:创建数据库连接时添加
consume_results=True参数,连接器会自动消费未读取的结果集,无需手动调用方法处理,连接配置修改示例:
with mysql.connector.connect( host="localhost", user='root', password='tt', database="dp", consume_results=True # 新增自动消费结果配置 ) as connection:
- 同步修复潜在问题:将LOAD DATA语句中的表名补全为
test_db.marks,Windows环境可将行终止符改为'\\r\\n'适配本地文件格式。
修改后核心执行逻辑参考:
with connection.cursor() as cursor: cursor.execute(clear_table_query) cursor.nextset() # 开启consume_results配置后可省略该调用 cursor.execute(create_table_query) cursor.nextset() # 补全表名,按需调整换行符配置 add_csv_query = "LOAD DATA INFILE 'C:/ProgramData/MySQL/MySQL Server 8.0/Uploads/result.txt' INTO TABLE test_db.marks FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY '\\r\\n' IGNORE 1 LINES;" cursor.execute(add_csv_query) cursor.nextset() cursor.execute("SELECT * FROM test_db.marks;") # 读取SELECT返回的查询结果 res = cursor.fetchall()
内容的提问来源于stack exchange,提问作者Hannon qaoud
相关产品推荐
相关产品推荐

