有没有办法将CSV文件数据直接复制到JSON或JSONb数组中?
示例:
CREATE TABLE mytable (
id serial PRIMARY KEY,
info jSONb -- or JSON
);
COPY mytable(info) FROM '/tmp/myfile.csv' HEADER csv;
注意:每个CSV行都映射到JSON数组。这是一个普通的CSV。
普通CSV(无JSON嵌入)... /tmp/myfile.csv
=
a,b,c
100,Mum,Dad
200,Hello,Bye
正确的COPY命令必须与通常的副本相同。
CREATE TEMPORARY TABLE temp1 (
a int, b text, c text
);
COPY temp1(a,b,c) FROM '/tmp/myfile.csv' HEADER csv;
INSERT INTO mytable(info) SELECT json_build_array(a,b,c) FROM temp1;
丑陋因为:
需要关于字段的小修知识,以及之前的CREATE TABLE
。
“大数据”需要一个大的临时表,因此丢失了CPU,磁盘和我的时间 - 表mytable
对每一行都有CHECK和UNIQUEs约束。
...需要多个SQL命令。
答案 0 :(得分:4)
不需要知道所有CSV列,只提取您所知道的内容。
在SQL CREATE EXTENSION PLpythonU;
使用:如果命令产生错误,如"无法打开扩展控制文件...没有这样的文件" 你需要安装pg -py额外包裹。在标准UBUNTU(16 LTS)很简单,apt install postgresql-contrib postgresql-plpython
。
CREATE FUNCTION get_csvfile(
file text,
delim_char char(1) = ',',
quote_char char(1) = '"')
returns setof text[] stable language plpythonu as $$
import csv
return csv.reader(
open(file, 'rb'),
quotechar=quote_char,
delimiter=delim_char,
skipinitialspace=True,
escapechar='\\'
)
$$;
INSERT INTO mytable(info)
SELECT jsonb_build_array(c[1],c[2],c[3])
FROM get_csvfile('/tmp/myfile1.csv') c;
split_csv()函数为defined here。 csv.reader
非常可靠(!)。
没有针对大型CSV进行测试......但是预期Python会有效。
这不是一个完美的解决方案,但它解决了主要问题,即
...大临时表,所以丢失了CPU,磁盘和我的时间" ...
这是我们这样做的方式,file_fdw
的解决方法!
采用您的约定以避免文件复制和文件权限混淆... CSV的标准文件路径。示例:/tmp/pg_myPrj_file.csv
使用魔术扩展
CREATE EXTENSION file_fdw;
CREATE SERVER files FOREIGN DATA WRAPPER file_fdw;
对于每个CSV文件myNewData.csv
,
3.1。为新文件scp
ln -sf $PWD/myNewData.csv /tmp/pg_socKer_file.csv
远程复制)
3.2。为新表配置 file_fdw (假设为mytable
)。
CREATE FOREIGN TABLE temp1 (a int, b text, c text)
SERVER files OPTIONS (
filename '/tmp/pg_socKer_file.csv',
format 'csv',
header 'true'
);
PS:在使用psql
运行SQL脚本后,遇到一些权限问题时,请按sudo chown -h postgres:postgres /tmp/pg_socKer_file.csv
更改链接的所有者。
3.3。使用 file_fdw 表作为源(假设填充mytable
)。
INSERT INTO mytable(info)
SELECT json_build_array(a,b,c) FROM temp1;
感谢@JosMac(和his tutorial)!
注意:如果有STDIN方法(存在??),将很容易,避免权限问题和使用绝对路径。请参阅this answer/discussion。