Ali*_*iBZ 54 postgresql export dump postgresql-9.3 json
有没有办法将 postgres 表数据作为 json 导出到文件?我需要逐行输出,例如:
{'id':1,'name':'David'}
{'id':2,'name':'James'}
...
Run Code Online (Sandbox Code Playgroud)
编辑:postgres 版本:9.3.4
Vér*_*ace 64
试试这里的基本介绍,以PostgreSQL和JSON。
此外,PostgreSQL 文档也很不错,因此请在此处尝试。检查pretty_bool选项。
您最初的问题是“有没有办法将 postgres 表数据导出为JSON”。你想要这种格式
{'id':1,'name':'David'}
{'id':2,'name':'James'}
...
Run Code Online (Sandbox Code Playgroud)
我没有正在运行的实例,PostgreSQL所以我下载、编译并安装了 9.4。
为了回答这个问题,我先CREATE编了一张表 (fred)
CREATE TABLE fred (mary INT, jimmy INT, paulie VARCHAR(20));
INSERT INTO fred VALUES (2, 43, 'asfasfasfd' );
INSERT INTO fred VALUES (3, 435, 'ererere' );
INSERT INTO fred VALUES (6, 43343, 'eresdfssfsfasfae');
Run Code Online (Sandbox Code Playgroud)
然后,检查:
test=# select * from fred;
mary | jimmy | paulie
------+-------+------------------
2 | 43 | asfasfasfd
3 | 435 | ererere
6 | 43343 | eresdfssfsfasfae
Run Code Online (Sandbox Code Playgroud)
然后我发出了这个命令
test=# COPY (SELECT ROW_TO_JSON(t)
test(# FROM (SELECT * FROM fred) t)
test-# TO '/paulstuff/sware/db/postgres/inst/myfile';
COPY 3
test=#
Run Code Online (Sandbox Code Playgroud)
然后我退出 psql 并列出文件 myfile.
test=# \q
[pol@polhost inst]$ more myfile
{"mary":2,"jimmy":43,"paulie":"asfasfasfd"}
{"mary":3,"jimmy":435,"paulie":"ererere"}
{"mary":6,"jimmy":43343,"paulie":"eresdfssfsfasfae"}
[pol@polhost inst]$
Run Code Online (Sandbox Code Playgroud)
(您可以尝试从
COPY (SELECT ROW_TO_JSON(t, TRUE) -- <-- Note addition of "TRUE" here!
Run Code Online (Sandbox Code Playgroud)
闲暇时)。
@offby1 指出输出(虽然对应于 OP 的问题)不正确JSON。@EvanCarroll 指出这\o也是一种输出到文件的方式,所以我在这个语句中结合了这两个小问题的解决方案(在此处的帮助下):
test=# \o out.json
test=# SELECT array_to_json(array_agg(fred), FALSE) AS ok_json FROM fred;
-- <-- "TRUE" here will produce plus
("+) signs in the output. "FALSE"
is the default anyway.
test=# \o
Run Code Online (Sandbox Code Playgroud)
给出:
[pol@polhost inst]$ more out.json
ok_json
----------------------------------------------------------------------------------------------------------------------------------------------
[{"mary":2,"jimmy":43,"paulie":"asfasfasfd"},{"mary":3,"jimmy":435,"paulie":"ererere"},{"mary":6,"jimmy":43343,"paulie":"eresdfssfsfasfae"}]
(1 row)
[pol@polhost inst]$
Run Code Online (Sandbox Code Playgroud)
最后,\@AdamGent 在他的帖子中提到了反斜杠 ( ) 问题。这有点棘手,但不诉诸查询后处理是可能的。瞧:
INSERT INTO fred VALUES (35, 5, 'wrew\sdfsd');
INSERT INTO fred VALUES (3, 44545, '\sdfs\\\sfs\\gf');
Run Code Online (Sandbox Code Playgroud)
并且因此使用 REGEXP_REPLACE(注意演员::TEXT)删除多余的黑斜线。
test=# \o slash.json
test=# SELECT REGEXP_REPLACE(ROW_TO_JSON(t)::TEXT, '\\\\', '\\', 'g')
test=# FROM (SELECT * FROM fred) AS t; -- I found that using a CTE was helpful for legibility
test=# \o
test=# \q
Run Code Online (Sandbox Code Playgroud)
给出:
[pol@polhost inst]$ more slash.json
regexp_replace
------------------------------------------------------
{"mary":2,"jimmy":43,"paulie":"asfasfasfd"}
{"mary":3,"jimmy":435,"paulie":"ererere"}
{"mary":6,"jimmy":43343,"paulie":"eresdfssfsfasfae"}
{"mary":35,"jimmy":5,"paulie":"wrew\sdfsd"}
{"mary":3,"jimmy":44545,"paulie":"\sdfs\\\sfs\\gf"}
(5 rows)
[pol@polhost inst]$
Run Code Online (Sandbox Code Playgroud)
(ps 至于@Zoltán 的评论——这可能是版本问题——无法复制!)。
Eva*_*oll 26
如果您正在使用,psql则根本没有理由使用\COPY。
\t
\a
\o file.json
SELECT row_to_json(r) FROM my_table AS r;
Run Code Online (Sandbox Code Playgroud)
这与我们使用 PostGIS 从数据库中获取 png/jpgs/tifs 以进行快速测试以及生成带有 PostgreSQL 扩展名的脚本文件的方法相同。
小智 9
对我来说,@Vérace的回答并没有保持的列名,但分配默认名称(f1,f2,等)来代替。我正在使用带有JSON 扩展名的PostgreSQL 9.1 。
如果要导出整个表,则不需要子查询。此外,这将维护列名。我使用了以下查询:
COPY (SELECT row_to_json(t) FROM fred as t) to '/home/pol/Downloads/software/postgres/inst/myfile';
Run Code Online (Sandbox Code Playgroud)
请在下面找到输出实际有效 JSON(即对象数组)的唯一答案。
\t
\a
\o data.json
select json_agg(t) FROM (SELECT * from table) t;
Run Code Online (Sandbox Code Playgroud)
(来源)
我将在Verace 的回答中添加一个特别的警告。如果您有带有反斜杠字符的文本列,则需要对输出的 JSON 文件进行后期处理:\ .
否则,您最多会得到重复(\-> \\),更糟的是完全无效的 JSON,即:
这个:
{ "f1" : "crap\""}.
Run Code Online (Sandbox Code Playgroud)
成为
{ "f1" : "crap\\""}.
Run Code Online (Sandbox Code Playgroud)
这看起来不错,但完全是无效的 JSON。
你可以用 sed替换\\成\:
sed -i -e 's/\\\\/\\/g' PG_OUT_JSON_FILE.json
Run Code Online (Sandbox Code Playgroud)
从Postgres COPY那里他们四处提及它:
目前,COPY TO 永远不会发出八进制或十六进制数字反斜杠序列,但它确实使用上面列出的其他序列作为这些控制字符。上表中未提及的任何其他反斜杠字符将被视为代表自身。但是,请注意不要添加不必要的反斜杠,因为这可能会意外地生成与数据结束标记 (.) 或空字符串(默认为 \N)匹配的字符串。这些字符串将在任何其他反斜杠处理完成之前被识别。
强烈建议生成 COPY 数据的应用程序将数据换行符和回车分别转换为 \n 和 \r 序列。目前可以用反斜线和回车来表示数据回车,用反斜线和换行符来表示数据换行。但是,在未来的版本中可能不接受这些表示。如果 COPY 文件在不同的机器之间传输(例如,从 Unix 到 Windows,反之亦然),它们也极易损坏。
COPY TO 将用 Unix 样式的换行符 ("\n") 终止每一行。在 Microsoft Windows 上运行的服务器改为输出回车/换行符(“\r\n”),但仅用于 COPY 到服务器文件;为了跨平台的一致性,无论服务器平台如何,COPY TO STDOUT 始终发送“\n”。COPY FROM 可以处理以换行符、回车符或回车/换行符结尾的行。为了降低由于没有反斜杠的换行符或回车而导致的错误风险,如果输入中的行结尾不完全相同,COPY FROM 将抱怨。