csv导入乱码主因是编码不匹配,需先用file -i或vs code确认真实编码再显式指定character set;截断多因max_allowed_packet小、字段含未转义换行符或列长度不足,严格模式关闭仅掩盖问题而非解决。
csv导入乱码:先看编码,别急着改sql模式
乱码不是STRICT_TRANS_TABLES开关能解决的——它只管数据合法性,不管字节怎么解。MySQL默认用utf8mb4接收客户端输入,但CSV文件可能是GBK、UTF-8 with BOM甚至ISO-8859-1。你用LOAD DATA INFILE直接读,它就按当前character_set_client硬解,错位了自然显示问号或截断中文。
实操建议:
- 用
file -i your_file.csv或VS Code底部编码栏确认真实编码 - 导入前显式指定:
LOAD DATA INFILE '/path/file.csv' CHARACTER SET gbk ... - Windows记事本另存为UTF-8(无BOM)比“UTF-8”选项更稳妥,后者常带BOM导致首字段多出

字段截断:长度不够和严格模式是两回事
Row 1 doesn't conform to the format: Column count doesn't match value count或某字段末尾被砍掉,大概率是max_allowed_packet太小,或者字段里混了未转义的换行符(\n)、双引号("),而LOAD DATA没配好ENCLOSED BY和ESCAPED BY。
实操建议:
- 查当前限制:
SHOW VARIABLES LIKE 'max_allowed_packet';,临时调大:SET GLOBAL max_allowed_packet = 268435456; - 如果CSV字段含换行或逗号,必须用
FIELDS ENCLOSED BY '"',且确保导出时已正确包裹 - 字段定义长度不足也会静默截断(比如
VARCHAR(10)存15个汉字),用DESCRIBE table_name;核对CHARACTER_MAXIMUM_LENGTH
关闭严格模式真能绕过截断?不能,还可能埋雷
关掉STRICT_TRANS_TABLES后,超长字段确实不报错,但会无声截断——这不是“解决问题”,是把错误从报错变成数据丢失。而且sql_mode是会话级的,你改了全局,其他应用可能依赖严格校验。
使用 qbo-mileage CLI 及用户凭证,从 Airtable、Outlook 或 Google Calendar 记录生成 QuickBooks Online 里程 CSV 文件。
实操建议:
- 临时会话内关闭仅用于诊断:
SET sql_mode = (SELECT REPLACE(@@sql_mode,'STRICT_TRANS_TABLES','')); - 不要在
my.cnf里全局关严格模式,尤其生产环境 - 真正要扩展长度,改表:
ALTER TABLE t MODIFY COLUMN c VARCHAR(500) CHARACTER SET utf8mb4;
用Python pandas read_csv再入库?注意双重编码转换
很多人转用pandas.read_csv()再to_sql(),以为能避开MySQL编码问题。其实只是把乱码时机往后推了:如果read_csv(encoding='utf-8')读错了源文件编码,DataFrame里数据已经坏;再插进MySQL,又经历一次charset协商,容易二次损坏。
实操建议:
- 读CSV时强制匹配真实编码:
pd.read_csv('x.csv', encoding='gbk') - 写入时明确驱动参数:
engine = create_engine('mysql+pymysql://...?charset=utf8mb4') - 验证是否成功:
SELECT HEX(col), LENGTH(col), CHAR_LENGTH(col) FROM t LIMIT 1;——中文应返回4字节/字符(utf8mb4),且LENGTH是CHAR_LENGTH的4倍
最麻烦的不是哪一步做错,而是乱码+截断同时发生时,你分不清是编码解错了,还是字段真被砍了,还是SQL模式掩盖了问题。得一项一项单独验证,别指望一个开关全搞定。










