如何将 CSV 复制为 JSON 字段
How to COPY CSV as JSON fields
有没有办法将 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 命令必须等同于下面的普通复制。
普通 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
知识。
因为 "big data" 需要一个大的临时 table,所以丢失了 CPU、磁盘和我的时间 — table mytable
每行都有 CHECKs 和 UNIQUEs 约束。
...需要超过 1 个 SQL 命令。
完美解决!
无需知道所有 CSV 列,只需提取您知道的内容。
Use at SQL CREATE EXTENSION PLpythonU;
:如果命令产生类似 "could not open extension control file ... No such file" 的错误,您需要安装 pg-py extra-packages .在标准 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
很靠谱(!).
未针对 big-big CSV 进行测试...但预计 Python 完成工作。
PostgreSQL 解决方法
这不是一个完美的解决方案,但它解决了主要问题,即
... big temporary table, so lost CPU, disk and my time"...
这就是我们的方法,file_fdw
的解决方法!
采用您的约定以避免文件复制和文件权限混淆... CSV 的标准文件路径。示例:/tmp/pg_myPrj_file.csv
初始化您的数据库或 SQL 带有魔术扩展的脚本,
CREATE EXTENSION file_fdw;
CREATE SERVER files FOREIGN DATA WRAPPER file_fdw;
对于每个 CSV 文件,myNewData.csv
,
3.1。为您的新文件 ln -sf $PWD/myNewData.csv /tmp/pg_socKer_file.csv
创建符号 link(或 scp
远程副本)
3.2。为您的新 table 配置 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:在 运行 SQL 脚本与 psql
之后,当遇到一些权限问题时,将 link 的所有者更改为 sudo chown -h postgres:postgres /tmp/pg_socKer_file.csv
.
3.3。使用 file_fdw table 作为来源(假设填充 mytable
)。
INSERT INTO mytable(info)
SELECT json_build_array(a,b,c) FROM temp1;
感谢@JosMac(和his tutorial)!
注意: 如果有 STDIN 方法(存在??),会很容易,避免权限问题和使用绝对路径。参见 。
有没有办法将 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 命令必须等同于下面的普通复制。
普通 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
知识。因为 "big data" 需要一个大的临时 table,所以丢失了 CPU、磁盘和我的时间 — table
mytable
每行都有 CHECKs 和 UNIQUEs 约束。...需要超过 1 个 SQL 命令。
完美解决!
无需知道所有 CSV 列,只需提取您知道的内容。
Use at SQL CREATE EXTENSION PLpythonU;
:如果命令产生类似 "could not open extension control file ... No such file" 的错误,您需要安装 pg-py extra-packages .在标准 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
很靠谱(!).
未针对 big-big CSV 进行测试...但预计 Python 完成工作。
PostgreSQL 解决方法
这不是一个完美的解决方案,但它解决了主要问题,即
... big temporary table, so lost CPU, disk and my time"...
这就是我们的方法,file_fdw
的解决方法!
采用您的约定以避免文件复制和文件权限混淆... CSV 的标准文件路径。示例:
/tmp/pg_myPrj_file.csv
初始化您的数据库或 SQL 带有魔术扩展的脚本,
CREATE EXTENSION file_fdw;
CREATE SERVER files FOREIGN DATA WRAPPER file_fdw;
对于每个 CSV 文件,
myNewData.csv
,3.1。为您的新文件
创建符号 link(或ln -sf $PWD/myNewData.csv /tmp/pg_socKer_file.csv
scp
远程副本)3.2。为您的新 table 配置 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:在 运行 SQL 脚本与 psql
之后,当遇到一些权限问题时,将 link 的所有者更改为 sudo chown -h postgres:postgres /tmp/pg_socKer_file.csv
.
3.3。使用 file_fdw table 作为来源(假设填充 mytable
)。
INSERT INTO mytable(info)
SELECT json_build_array(a,b,c) FROM temp1;
感谢@JosMac(和his tutorial)!
注意: 如果有 STDIN 方法(存在??),会很容易,避免权限问题和使用绝对路径。参见