Pet*_*uss 3 csv postgresql jsonb
有没有办法将 CSV 文件数据直接复制到 JSON 或 JSONb 数组中?
例子:
CREATE TABLE mytable (
id serial PRIMARY KEY,
info jSONb -- or JSON
);
COPY mytable(info) FROM '/tmp/myfile.csv' HEADER csv;
Run Code Online (Sandbox Code Playgroud)
注意:每个 CSV 行都映射到一个 JSON 数组。这是一个普通的CSV。
普通 CSV(没有嵌入 JSON)... /tmp/myfile.csv
=
a,b,c
100,Mum,Dad
200,Hello,Bye
Run Code Online (Sandbox Code Playgroud)
正确的 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;
Run Code Online (Sandbox Code Playgroud)
它很丑,因为:
需要一个修道院有关领域的知识,和以前CREATE TABLE
用它。
“大数据”需要一个大的临时表,因此丢失了 CPU、磁盘和我的时间——该表mytable
的每一行都有 CHECK 和 UNIQUEs 约束。
... 需要 1 个以上的 SQL 命令。
不需要知道所有的 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;
Run Code Online (Sandbox Code Playgroud)
该split_csv()函数,这里定义。该csv.reader
是非常可靠的(!)。
未针对大型 CSV 进行测试...但预期 Python 可以完成工作。
这不是一个完美的解决方案,但它解决了主要问题,即
...大的临时表,因此丢失了 CPU、磁盘和我的时间”...
这就是我们这样做的方式,一种解决方法file_fdw
!
采用您的约定以避免文件复制和文件权限混淆... CSV 的标准文件路径。例子:/tmp/pg_myPrj_file.csv
使用魔法扩展名初始化您的数据库或 SQL 脚本,
CREATE EXTENSION file_fdw;
CREATE SERVER files FOREIGN DATA WRAPPER file_fdw;
Run Code Online (Sandbox Code Playgroud)
对于每个 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'
);
Run Code Online (Sandbox Code Playgroud)
PS:用 运行SQL 脚本后psql
,当出现权限问题时,将链接的所有者改为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;
Run Code Online (Sandbox Code Playgroud)
感谢@JosMac(和他的教程)!
注意:如果有 STDIN 方法(存在??),将很容易,避免权限问题和使用绝对路径。请参阅此答案/讨论。
归档时间: |
|
查看次数: |
2363 次 |
最近记录: |