各数据库导入空值需按规则处理:MySQL用NULLIF或指定NULL字符串,Pandas需na_values参数,PostgreSQL认'N'或自定义NULL标识,SQL Server依赖KEEPNULLS和字面量NULL。
MySQL LOAD DATA INFILE 把空字符串当 NULL 导入失败
默认情况下,load data infile 不会把 csv 里的空字段(如 ,,)自动转成 sql 的 null,而是存成空字符串 ''。除非显式告诉它哪些值该作为空值处理。
- 必须用
NULL字面量(即字段里真写个NULL)+\N或自定义NULL字符串,才能触发转换 - 空字段(两个逗号紧挨着)默认被当作
'',哪怕列定义是INT NULL或VARCHAR(255) NULL - 如果源 CSV 用
\N表示缺失值,加NULL TERMINATED BY '\N'没用——这是错的;正确做法是用SET col_name = NULLIF(col_name, '')或提前指定NULL字符 - 推荐写法:
LOAD DATA INFILE '/path/data.csv' INTO TABLE t1 FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY ' ' (@c1,@c2,@c3) SET id = NULLIF(@c1,''), name = NULLIF(@c2,''), score = NULLIF(@c3,'');
Pandas read_csv 中空字符串不自动转 NaN,导致 to_sql 写入全变成 ''
read_csv 默认只把 NaN、NULL、None、空格字符串等有限几种识别为缺失值,纯空字段("")默认仍为 str 类型的空字符串,不会自动升格为 np.nan。
- 关键参数是
na_values:比如na_values=['', 'NULL', '\N']才能让空字符串进 DataFrame 就是NaN - 注意
keep_default_na=True(默认)会叠加内置的 na 值列表,可能造成意外覆盖;设为False后只认你给的na_values - 导入后用
df.dtypes看列类型,如果本该是数值却还是object,大概率是混了空字符串没转NaN,后续to_sql就会强转成''插入 - 示例:
pd.read_csv('data.csv', na_values=['', 'NULL'], keep_default_na=False)
PostgreSQL COPY 命令对 NULL 字符串敏感,且大小写严格
COPY 默认只认 N 作为 NULL 标识符(注意是反斜杠大写 N),不是 NULL,也不是小写
,更不是空字段。
- CSV 中想表示 NULL,得写成
N,且不能加引号("N"是字符串,不是 NULL) - 可用
NULL 'xyz'自定义,比如COPY t FROM '/f.csv' WITH (NULL 'NULL');,这时 CSV 里写NULL才生效 - 字段含双引号或逗号时,必须用
QUOTE '"'+ESCAPE配合,否则"a,b",N会被误切 - 错误现象:日志报
invalid input syntax for type integer: "",说明空字符串传进来了,不是 N —— 检查导出端是否用了NULL AS 'N'
SQL Server BULK INSERT 把空字段当 0 或空字符串,不认 N
SQL Server 的 BULK INSERT 不支持 N,也不默认将空字段转为 NULL;它依赖字段定义中的 NULL 属性和格式文件(或 FIRSTROW/FIELDTERMINATOR 组合)来判断。
- 最稳的方式是用格式文件(.fmt)明确定义每列是否允许 NULL,并指定空字段映射行为
- 若不用格式文件,确保目标列允许 NULL,且在 CSV 中用
NULL字符串(非引号包裹),再配合KEEPNULLS选项:BULK INSERT t FROM 'data.csv' WITH (FIELDTERMINATOR=',', ROWTERMINATOR=' ', KEEPNULLS); -
KEEPNULLS是关键:没有它,即使 CSV 里写了NULL,也会被当成字面量插入;有它,才触发字符串'NULL'→ SQLNULL转换 - 注意:SQL Server 不识别
\N或空字段,也不受na_values影响 —— 这是客户端行为,BULK INSERT 是服务端直读文件
不同数据库对“空”的理解差得挺远,同一份 CSV 在 MySQL 里加 NULLIF 能行,在 PostgreSQL 里就得改内容为 N,到了 SQL Server 又得靠 KEEPNULLS 和字面量 NULL。最容易漏的是没确认目标列是否真允许 NULL,或者导出时根本没按目标库要求生成对应空值标记。










