MySQL中设字段分隔符用FIELDS TERMINATED BY,编码必须显式写CHARACTER SET utf8mb4且位于FIELDS之前;PostgreSQL用\copy时通过DELIMITER和client_encoding控制;pandas需用encoding='utf-8-sig'处理BOM。
MySQL 的 LOAD DATA INFILE 怎么设字段分隔符和编码
直接说结论:字段分隔符用 fields terminated by,编码必须用 character set 显式声明,且顺序不能错——character set 要写在 fields 之前,否则 mysql 会忽略编码设置,读出乱码。
常见错误现象是 CSV 里有中文,导入后变成问号或 Mojibake(如 “æäºº”),但 SHOW CREATE TABLE 看表字符集明明是 utf8mb4——问题大概率出在没在 LOAD DATA 语句里指定 CHARACTER SET utf8mb4。
-
LOAD DATA INFILE默认按服务器character_set_database解析文件,不是按表或列的字符集 - Windows 记事本保存的 CSV 多为
GBK或带 BOM 的UTF-8,Linux 下常用无 BOMUTF-8,不匹配就炸 - 字段分隔符不止
,:Excel 导出可能用;,日志类 CSV 可能用\t,得对应写FIELDS TERMINATED BY ';'或FIELDS TERMINATED BY '\t' - 如果首行是标题,加
IGNORE 1 ROWS;字段含引号包裹(如"Smith, John"),要加OPTIONALLY ENCLOSED BY '"'
示例(UTF-8 编码、逗号分隔、带标题行):
LOAD DATA INFILE '/var/lib/mysql-files/data.csv' INTO TABLE my_table CHARACTER SET utf8mb4 FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n' IGNORE 1 ROWS;
PostgreSQL 用 COPY 导入 CSV:编码和分隔符在哪设
PostgreSQL 的 COPY 不接受文件路径直接读本地文件(除非你是 superuser 且走服务端路径),更常用的是 psql 客户端的 \copy 命令——它走客户端本地读取,编码由客户端决定,这才是可控的关键。
容易踩的坑:用 COPY(服务端命令)时,数据库会按 client_encoding 解析文件内容,但如果你本地终端是 GBK,而 CSV 是 UTF-8,就会乱码;\copy 则自动继承 psql 连接时的 client_encoding,只要连接时指定了就安全。
- 执行前先确认连接编码:
SHOW client_encoding;,不对就SET client_encoding = 'UTF8'; -
\copy命令里用DELIMITER ','设分隔符,CSV模式自动处理引号、换行、空值,比手动写WITH (FORMAT csv)更省心 - Windows 下路径注意双反斜杠或正斜杠:
\copy my_table FROM 'C:/data.csv' WITH (FORMAT csv, HEADER true); - 如果 CSV 有 BOM(尤其 Excel 生成),PostgreSQL 会把 BOM 当作第一列内容,导致列数错位——用
iconv -f UTF-8 -t UTF-8//IGNORE file.csv > clean.csv先清理
Python pandas read_csv() 编码和分隔符填错的典型表现
报错 UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd6 in position 123?或者读出来第一列全是 id?说明编码或 BOM 没对上。pandas 默认用 utf-8,但很多国产软件导出的是 gbk 或带 BOM 的 utf-8-sig。
使用 qbo-mileage CLI 及用户凭证,从 Airtable、Outlook 或 Google Calendar 记录生成 QuickBooks Online 里程 CSV 文件。
别靠猜,先用 file 命令或 VS Code 底部编码提示看真实编码;BOM 存在时,强制用 encoding='utf-8-sig',它会自动剥离 BOM,比 utf-8 安全得多。
-
sep参数不只支持字符串:sep=r'\s+'可读空格/制表符混合分隔,sep=None启用 Python 自动推断(适合格式混乱的老数据) - 中文列名读成乱码?不是编码问题,是
read_csv()把第一行当列名用了,但编码错了——所以列名本身也乱,本质还是encoding填错 - 大文件内存爆了?加
chunksize=10000流式读,再用to_sql()分批写入,别一次性df.to_sql() - 日期列没解析?加
parse_dates=['date_col'],否则 pandas 当成字符串,后续groupby或resample全失效
字段分隔符是逗号,但内容里也有逗号 —— 怎么不出错
标准 CSV 规范要求:字段含逗号、换行、引号时,必须用双引号包裹,且内部引号要转义为两个双引号("a""b")。只要源文件遵守这个规则,所有主流工具都能正确解析。
现实是很多“CSV”根本不合规:比如用 Excel 直接复制粘贴生成的文本,或某些旧系统导出的“伪 CSV”,字段没引号、逗号没转义——这时候硬按 CSV 解析必然错列。
- MySQL
LOAD DATA遇到未包裹的逗号,会直接截断字段,后面所有列偏移,且不报错 - pandas
read_csv(sep=',')默认启用quoting=csv.QUOTE_MINIMAL,但若字段没引号,它仍会按逗号切,结果就是列数爆炸 - 救急办法:用正则预处理,比如把
,(?=(?:[^"]*"[^"]*")*[^"]*$)匹配“不在引号内的逗号”,再替换成其他符号(如␟),然后用那个符号当分隔符 - 长期建议:推动上游系统改用制表符(
\t)分隔,它天然不含在普通文本中,比逗号鲁棒得多
真正麻烦的从来不是怎么设参数,而是没人告诉你那个“CSV”其实根本不是 CSV。










