Postgres row_to_json生成带有双重转义引号的无效JSON

And*_*Ray 9 postgresql json

创建JSON导出时,Postgres会错误地引用引号.请注意以下更新中的双引号...

UPDATE models SET column='"hello"' WHERE id=1;

COPY (SELECT row_to_json(models)
    FROM (SELECT column FROM shaders WHERE id=1) shaders)
    TO '/output.json';
Run Code Online (Sandbox Code Playgroud)

output.json的内容:

{"column":"\\"hello\\""}
Run Code Online (Sandbox Code Playgroud)

您可以看到引号被不正确地转义,并且它会创建无效的JSON.它应该是:

{"column":"\"hello\""}
Run Code Online (Sandbox Code Playgroud)

我该如何解决这个Postgres错误或解决它?

Sim*_*stö 13

这与JSON无关.它与COPY命令中的文本格式(默认)处理反斜杠的方式有关.从PostgreSQL文档 - COPY:

\可以在COPY数据中使用反斜杠字符()来引用可能被视为行或列分隔符的数据字符.特别是,如果以下字符作为列值的一部分出现,则必须以反斜杠开头:反斜杠本身,换行符,回车符和当前分隔符.

(强调我的.)
您可以使用CSV格式并将引号字符从doublequote更改为其他内容来解决它.

展示:

SELECT row_to_json(row('"hello"'))
 | "{"f1":"\"hello\""}" |
Run Code Online (Sandbox Code Playgroud)


COPY (SELECT row_to_json(row('"hello"'))) TO '/output.json';
 | {"f1":"\\"hello\\""} |
Run Code Online (Sandbox Code Playgroud)


COPY (SELECT row_to_json(row('"hello"'))) TO '/output.json' CSV QUOTE '$';
 | {"f1":"\"hello\""} |
Run Code Online (Sandbox Code Playgroud)


Zol*_*tán 7

如果您确定该字符$或您选择的任何特殊引号字符没有出现在您的字符串中,那么 Simo Kivistö 的答案就有效。就我而言,我必须导出一个非常大的表,并且没有出现在字符串中的特定字符。

为了解决这个问题,我将COPY命令的输出通过管道传输sed到恢复引号的双重转义:

psql -c "COPY (SELECT row_to_json(t) from my_table as t) to STDOUT;" |
  sed 's/\\"/\"/g' > my_table.json
Run Code Online (Sandbox Code Playgroud)

sed我正在使用的表达式简单地替换了\\"with 的出现\"