如何解决LOAD DATA导入MySQL时因描述含换行导致的数据错位问题?
解决MySQL LOAD DATA因字段含换行符导致数据错位的问题
这个问题我之前踩过坑!核心原因就是你description字段里的换行符,和你指定的LINES TERMINATED BY '\n'冲突了——MySQL会把字段内的换行当成一条新记录的起始,直接打乱了列的对应关系,strip()没用是因为它只清掉字符串首尾的换行,中间的换行还在。给你几个靠谱的解决思路:
方法1:换用无冲突的字段分隔符
找一个绝对不会出现在任何字段内容里的字符串当分隔符,比如制表符\t,或者更独特的标记如|||DATA_SEP|||,彻底避免和字段内的字符冲突。
修改Python写入代码:
# 用制表符\t作为分隔符示例 each_file.write(f"{url}\t{rep_name}\t{b['_source']['dataset']['ID']}\t{title}\t{description}\n")
修改MySQL导入语句:
cursor.execute (""" LOAD DATA LOCAL INFILE '%s' INTO TABLE testseprator FIELDS TERMINATED by '\t' LINES TERMINATED BY '\n' (link,repo_name,dataset_id,title,description) SET id = NULL """ %(file1,))
方法2:转义字段内的换行符
写入文件时把description里的换行符替换成转义字符,导入MySQL后再转回来,让MySQL不会把它当成行结束符。
修改Python写入代码:
# 把换行符转义成\\n,回车转义成\\r escaped_desc = description.replace('\n', '\\n').replace('\r', '\\r') each_file.write(f"{url}|*|{rep_name}|*|{b['_source']['dataset']['ID']}|*|{title}|*|{escaped_desc}\n")
导入后还原换行符:
导入完成后执行SQL语句把转义字符还原:
UPDATE testseprator SET description = REPLACE(REPLACE(description, '\\n', '\n'), '\\r', '\r');
注意:如果你的
description本身就包含\n字符串,这个方法会有误替换,需要根据数据情况判断是否适用。
方法3:用引号包裹字段(最稳妥的标准方案)
这是CSV文件的标准处理方式——用引号把每个字段包裹起来,告诉MySQL字段内的换行符和分隔符都是内容的一部分,不要当成记录分隔。
修改Python写入代码:
先写一个辅助函数处理字段内的引号(把单个双引号替换成两个双引号,符合SQL的转义规则):
def escape_sql_field(s): # 处理空值,替换字段内的双引号为两个双引号 return s.replace('"', '""') if s else '' # 每个字段用双引号包裹 line = ( f'"{escape_sql_field(url)}"|*|' f'"{escape_sql_field(rep_name)}"|*|' f'"{escape_sql_field(b["_source"]["dataset"]["ID"])}"|*|' f'"{escape_sql_field(title)}"|*|' f'"{escape_sql_field(description)}"\n' ) each_file.write(line)
修改MySQL导入语句:
加上ENCLOSED BY '"'参数,让MySQL识别引号包裹的字段:
cursor.execute (""" LOAD DATA LOCAL INFILE '%s' INTO TABLE testseprator FIELDS TERMINATED by '|*|' ENCLOSED BY '"' LINES TERMINATED BY '\n' (link,repo_name,dataset_id,title,description) SET id = NULL """ %(file1,))
这个方法兼容性最好,能同时处理字段内的换行符、分隔符等特殊情况,推荐优先使用。
内容的提问来源于stack exchange,提问作者nina_dev
相关产品推荐
相关产品推荐

