postgresql json到列错误字符与值必须转义

bil*_*ill 3 postgresql json insert special-characters

我尝试从包含 json 行的表中加载一些数据。
有一个字段可以包含特殊字符,如 \t 和 \r,我想将它们保留在新表中。

这是我的文件:

{"text_sample": "this is a\tsimple test", "number_sample": 4}
Run Code Online (Sandbox Code Playgroud)

这是我所做的:

Drop table if exists temp_json;
Drop table if exists test;
create temporary table temp_json (values text);

copy temp_json from '/path/to/file';

create table test as (select 
        (values->>'text_sample') as text_sample,
        (values->>'number_sample') as number_sample
        from   (
           select replace(values,'\','\\')::json as values
           from   temp_json
       ) a);
Run Code Online (Sandbox Code Playgroud)

我不断收到此错误:

ERROR:  invalid input syntax for type json
DETAIL:  Character with value 0x09 must be escaped.
CONTEXT:  JSON data, line 1: ...g] Objection to PDDRP Mediation (was Re: Call for...
Run Code Online (Sandbox Code Playgroud)

我需要如何转义这些字符?
多谢

l m*_*zhi 5

正如Andrew Dunstan 的 PostgreSQL 和技术博客中提到的

在文本模式下,COPY 将因 JSON 中存在反斜杠而失效。因此,例如,任何包含嵌入式双引号、嵌入式换行符或根据 JSON 规范需要转义的任何其他字段都将导致失败。在文本模式下,您对其工作方式几乎没有控制权 - 例如,您无法指定不同的 ESCAPE 字符。所以文本模式根本不起作用。

所以我们必须转向CSV格式化模式。

copy the_table(jsonfield) 
from '/path/to/jsondata' 
csv quote e'\x01' delimiter e'\x02';
Run Code Online (Sandbox Code Playgroud)

在官方文档sql-copy中,列出了一些参数:

COPY table_name [ ( column_name [, ...] ) ]
    FROM { 'filename' | PROGRAM 'command' | STDIN }
    [ [ WITH ] ( option [, ...] ) ]
    [ WHERE condition ]

where option can be one of:

    FORMAT format_name
    FREEZE [ boolean ]
    DELIMITER 'delimiter_character'
    NULL 'null_string'
    HEADER [ boolean ]
    QUOTE 'quote_character'
    ESCAPE 'escape_character'
    FORCE_QUOTE { ( column_name [, ...] ) | * }
    FORCE_NOT_NULL ( column_name [, ...] )
    FORCE_NULL ( column_name [, ...] )
    ENCODING 'encoding_name'
Run Code Online (Sandbox Code Playgroud)
  • 格式
    • 选择要读取或写入的数据格式:文本、csv(逗号分隔值)或二进制。默认为文本。
  • 引用
    • 指定引用数据值时要使用的引用字符。默认是双引号。这必须是单个单字节字符。仅当使用 CSV 格式时才允许使用此选项。
  • 分隔符
    • 指定分隔文件每行(行)内的列的字符。文本格式默认为制表符,CSV 格式默认为逗号。这必须是单个单字节字符。使用二进制格式时不允许使用此选项。
  • 无效的
    • 指定表示空值的字符串。在文本格式中默认为 \N(反斜杠-N),在 CSV 格式中默认为不带引号的空字符串。对于不想区分空值和空字符串的情况,即使是文本格式,您也可能更喜欢空字符串。使用二进制格式时不允许使用此选项。
  • 标头
    • 指定文件包含标题行,其中包含文件中每列的名称。在输出时,第一行包含表中的列名,在输入时,第一行将被忽略。仅当使用 CSV 格式时才允许使用此选项。