创建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';
output.json的内容:
{"column":"\\"hello\\""}
您可以看到引号未正确转义,并且会创建无效的JSON。 它应该是:
{"column":"\"hello\""}
如何解决这个Postgres错误或解决它?
答案 0 :(得分:11)
这与JSON无关。它是关于COPY
命令中文本格式(默认)处理反斜杠的方式。来自the PostgreSQL documentation - COPY:
反斜杠字符(
\
)可以在COPY数据中用于引用可能被视为行或列分隔符的数据字符。特别是,如果以下字符作为列值的一部分出现,则必须以反斜杠开头:反斜杠本身,换行符,回车符和当前分隔符。
(强调我的。)
您可以使用CSV格式并将引号字符从doublequote更改为其他内容来解决它。
演示:
SELECT row_to_json(row('"hello"'))
| "{"f1":"\"hello\""}" |
COPY (SELECT row_to_json(row('"hello"'))) TO '/output.json';
| {"f1":"\\"hello\\""} |
COPY (SELECT row_to_json(row('"hello"'))) TO '/output.json' CSV QUOTE '$';
| {"f1":"\"hello\""} |
答案 1 :(得分:3)
如果您确定角色$
或您选择的特殊引号字符不出现在您的字符串中,则SimoKivistö的答案有效。在我的情况下,我必须导出一个非常大的表,并且没有特殊的字符没有出现在字符串中。
要解决此问题,我将COPY
命令的输出传送到sed
以恢复引号的双重转义:
psql -c "COPY (SELECT row_to_json(t) from my_table as t) to STDOUT;" |
sed 's/\\"/\"/g' > my_table.json
我正在管道的sed
表达式只是用\\"
替换\"
的出现次数。