我搜索并发现了一些与postgres csv进口有关的帖子,但没有解决我当前问题的任何内容 .
我一直使用postgres copy 命令将来自异构数据源的数据导入我们的系统 . 目前正在努力争取1亿行.csv文件,逗号引用分隔 . 问题是像这样的行:
009098,0981098094,"something","something else",""this one, well, is a problem"", "another thing"
用逗号括起来的双引号括起来的字段 . 字段未正确解析,我收到错误:
"ERROR: extra data after last expected column"
通常当出现这种情况时,我会特意处理有问题的行,但是这个文件非常庞大,我希望有一些更通用的方法来防御它 . 要求修改数据格式是不可能的 .
copy mytable from '/path/to/file.csv' csv header quote '"'
2 回答
这是格式错误的CSV . 你加倍双引号在引号字段中嵌入双引号;例如:
有三个值:
where
is "pancakes"
house?
你遇到麻烦的那一行有两倍的双引号:
我不认为COPY可以做任何事情,因为正确的版本是模棱两可的:它应该是
"this one, well, is a problem"
还是"""this one, well, is a problem"""
?我想你必须手工解决它 . 如果你可以唯一地识别断行,那么快速
sed
单行应该能够完成这项工作 .出于参考目的,我在CSV标准中看到的最接近的事情是RFC 4180,第二部分就是这样说的:
以下是基于Kernighan和Plauger的The Practice of Programming的CSV代码的代码,该代码已经过调整以处理您奇怪的格式错误的CSV数据 . (这不是很难做到;我已经有了主要的代码工作和打包,所以我只需要添加CSV输出函数并修改
advquoted()
函数来处理这个问题中的奇怪格式 .csv2.h
csv2.c
使用
-DTEST
编译代码以使用示例main()
函数创建程序 . 你需要一个C99编译器;main()
中的代码使用VLA(可变长度数组) . 你可以通过动态内存分配或悲观(过度杀伤)内存分配来避免这种情况(如今几千个指针的数组不会杀死大多数系统,但很少有CSV文件每行会有几千个字段) .示例数据
基于问题中的数据 .
示例输出
字段打印两次,一次测试场提取,一次测试现场打印 . 您可以通过删除除
csvputline()
之外的打印来简化输出,以将文件从格式错误的CSV转换为正确形成的CSV .