将 Postgres 表导出为 json

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

试试这里的基本介绍,以PostgreSQLJSON

此外,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 的评论——这可能是版本问题——无法复制!)。

  • 如果您的列中有任何“反斜杠”,这将 **不** 工作!!!!仔细阅读 COPY 文档,因为它对 `backslash` 字符做了特殊处理(比如添加另一个反斜杠)。 (3认同)
  • 这似乎正是原始海报想要的。但是请注意,虽然每个 _row_ 都是正确的 JSON,但行的 _collection_ 不是,因为它缺少分隔行的逗号和围绕它们的方括号。 (2认同)

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 扩展名的脚本文件的方法相同。

  • 请注意,文件“file.json”中的输出不是 JSON,而是该文件中的每一行都是表示一行的 JSON 对象。但该文件完全不是有效的 JSON,您需要将整个文件包装在 `[` 和 `]` 之间,并在行末尾添加所需的逗号。 (3认同)
  • 是的,如上所述,因为每一行都是一行,所以最终的输出也称为 JSON 行格式(其中每一行都是一个有效的 JSON 对象)。无论如何,大多数工具都会自动处理这种格式,例如“jq”。 (2认同)

小智 9

对我来说,@Vérace的回答并没有保持的列名,但分配默认名称(f1f2,等)来代替。我正在使用带有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)


Gun*_*ner 9

请在下面找到输出实际有效 JSON(即对象数组)的唯一答案

\t
\a
\o data.json
select json_agg(t) FROM (SELECT * from table) t;
Run Code Online (Sandbox Code Playgroud)

来源

  • 应该更高。谢谢你! (3认同)

Ada*_*ent 7

我将在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 将抱怨。