【问题标题】:Loading json data from a file into Postgres将文件中的 json 数据加载到 Postgres
【发布时间】:2016-01-12 18:56:30
【问题描述】:

我需要将多个 JSON 文件中的数据加载到 Postgres 表中,每个文件中都有多个记录。我正在使用以下代码,但它不起作用(我在 Windows 上使用 pgAdmin III)

COPY tbl_staging_eventlog1 ("EId", "Category", "Mac", "Path", "ID")
from 'C:\\SAMPLE.JSON' 
delimiter ','
;

SAMPLE.JSON 文件的内容是这样的(给出两条记录):

[{"EId":"104111","Category":"(0)","Mac":"ABV","Path":"C:\\Program Files (x86)\\Google","ID":"System.Byte[]"},{"EId":"104110","Category":"(0)","Mac":"BVC","Path":"C:\\Program Files (x86)\\Google","ID":"System.Byte[]"}]

【问题讨论】:

标签: json postgresql


【解决方案1】:

试试这个:

BEGIN;
-- let's create a temp table to bulk data into
create temporary table temp_json (values text) on commit drop;
copy temp_json from 'C:\SAMPLE.JSON';

-- uncomment the line above to insert records into your table
-- insert into tbl_staging_eventlog1 ("EId", "Category", "Mac", "Path", "ID") 

select values->>'EId' as EId,
       values->>'Category' as Category,
       values->>'Mac' as Mac,
       values->>'Path' as Path,
       values->>'ID' as ID      
from   (
           select json_array_elements(replace(values,'\','\\')::json) as values 
           from   temp_json
       ) a; 
COMMIT;

【讨论】:

  • 非常感谢!这很有帮助
  • @anil: 所以你应该接受这个答案是正确的。
  • @JoshuaRobinson :您必须在单个事务中运行整个脚本。可能您将它作为“脚本”运行,并且当它运行“选择”子句时,临时表已经被删除(在提交删除时)。
  • 很好也需要像这样转换 Id (CAST(values->>'ID' AS integer)) AS ID
  • 这个解决方案给了我一个错误:CREATE TABLE COPY 1 psql:insertJson.sql:64: ERROR: invalid input syntax for type json DETAIL: Expected "," or "}", but found " 1.0”。上下文:JSON 数据,第 1 行:...number": null, "annotations": "
【解决方案2】:

Andrew Dunstan's PostgreSQL and Technical blog中所述

在文本模式下,COPY 将被 JSON 中的反斜杠简单地破坏。因此,例如,任何包含嵌入双引号或嵌入换行符的字段,或任何其他需要根据 JSON 规范进行转义的字段都将导致失败。在文本模式下,您几乎无法控制它的工作方式——例如,您不能指定不同的 ESCAPE 字符。所以文本模式根本行不通。

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

copy the_table(jsonfield) 
from '/path/to/jsondata' 
csv quote e'\x01' delimiter e'\x02';

在官方文档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'
  • 格式
    • 选择要读取或写入的数据格式:文本、csv(逗号分隔值)或二进制。默认为文本。
  • 报价
    • 指定引用数据值时要使用的引用字符。默认为双引号。这必须是一个单字节字符。仅当使用 CSV 格式时才允许使用此选项。
  • 分隔符
    • 指定分隔文件每一行(行)内的列的字符。默认是文本格式的制表符,CSV 格式的逗号。这必须是一个单字节字符。使用二进制格式时不允许使用此选项。
    • 指定表示空值的字符串。默认为文本格式的 \N(反斜杠-N),以及 CSV 格式的不带引号的空字符串。对于不想区分空字符串和空字符串的情况,您可能更喜欢文本格式的空字符串。使用二进制格式时不允许使用此选项。
  • 标题
    • 指定文件包含一个标题行,其中包含文件中每一列的名称。输出时,第一行包含表中的列名,输入时,第一行被忽略。仅当使用 CSV 格式时才允许使用此选项。

【讨论】:

    【解决方案3】:

    您可以使用spyql。 运行以下命令将生成 INSERT 语句,您可以通过管道将其导入 psql:

    $ jq -c .[] *.json | spyql -Otable=tbl_staging_eventlog1 "SELECT json->EId, json->Category, json->Mac, json->Path, json->ID FROM json TO sql"
    INSERT INTO "tbl_staging_eventlog1"("EId","Category","Mac","Path","ID") VALUES ('104111','(0)','ABV','C:\Program Files (x86)\Google','System.Byte[]'),('104110','(0)','BVC','C:\Program Files (x86)\Google','System.Byte[]');
    

    jq 用于将当前目录中所有 json 文件的 json 数组转换为 json 行(每行 1 个 json 对象),然后 spyql 负责将 json 行转换为 INSERT 语句。

    将数据导入 PostgreSQL:

    $ jq -c .[] *.json | spyql -Otable=tbl_staging_eventlog1 "SELECT json->EId, json->Category, json->Mac, json->Path, json->ID FROM json TO sql" | psql  -U your_user_name -h your_host your_database
    

    免责声明:我是 spyql 的作者。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-05
      • 1970-01-01
      • 2012-06-10
      • 1970-01-01
      相关资源
      最近更新 更多