如何将JSON文件导入PostgreSQL?

Jer*_*een 20 sql postgresql json

例如,我有一个文件customers.json,它是一个对象数组(严格形成),并且它非常简单(没有嵌套对象),这样(重要的是:它已经包含了ids):

[
  {
    "id": 23635,
    "name": "Jerry Green",
    "comment": "Imported from facebook."
  },
  {
    "id": 23636,
    "name": "John Wayne",
    "comment": "Imported from facebook."
  }
]
Run Code Online (Sandbox Code Playgroud)

我想将它们全部导入我的postgres db到表中customers.

我发现了一些相当困难的方法,当我将它作为json类型的列导入到像其中列出的对象imported_json命名的表和列data,然后使用sql获取这些值并将其插入到真实的表中.

但有没有一种简单的方法导入json到postgres没有触及sql?

a_h*_*ame 31

您可以将JSON提供给SQL语句,该语句提取信息并将其插入表中.如果JSON属性具有与表列完全相同的名称,则可以执行以下操作:

with customer_json (doc) as (
   values 
    ('[
      {
        "id": 23635,
        "name": "Jerry Green",
        "comment": "Imported from facebook."
      },
      {
        "id": 23636,
        "name": "John Wayne",
        "comment": "Imported from facebook."
      }
    ]'::json)
)
insert into customer (id, name, comment)
select p.*
from customer_json l
  cross join lateral json_populate_recordset(null::customer, doc) as p
on conflict (id) do update 
  set name = excluded.name, 
      comment = excluded.comment;
Run Code Online (Sandbox Code Playgroud)

将插入新客户,现有客户将更新."魔术"部分是json_populate_recordset(null::customer, doc)生成JSON对象的关系表示的部分.


上面假设一个像这样的表定义:

create table customer 
(
  id        integer primary key,
  name      text not null,
  comment   text
);
Run Code Online (Sandbox Code Playgroud)

如果数据是作为文件提供的,则需要先将该文件放入数据库中的某个表中.像这样的东西:

create unlogged table customer_import (doc json);
Run Code Online (Sandbox Code Playgroud)

然后将文件上传到该表的单行,例如使用\copy命令psql(或SQL客户端提供的任何内容):

\copy customer_import from 'customers.json' ....
Run Code Online (Sandbox Code Playgroud)

然后你可以使用上面的语句,只需删除CTE并使用登台表:

insert into customer (id, name, comment)
select p.*
from customer_import l
  cross join lateral json_populate_recordset(null::customer, doc) as p
on conflict (id) do update 
  set name = excluded.name, 
      comment = excluded.comment;
Run Code Online (Sandbox Code Playgroud)


Doc*_*val 25

事实证明,使用命令行psql工具将多行JSON对象导入postgres数据库中的JSON列是一种简单的方法,而无需将JSON显式嵌入到SQL语句中.postgresql文档中记录了该技术,但它有点隐藏.

诀窍是使用反引号将JSON加载到psql变量中.例如,给定/tmp/test.json中的多行JSON文件,例如:

{
  "dog": "cat",
  "frog": "frat"
}
Run Code Online (Sandbox Code Playgroud)

我们可以使用以下SQL将其加载到临时表中:

sql> \set content `cat /tmp/test.json`
sql> create temp table t ( j jsonb );
sql> insert into t values (:'content');
sql> select * from t;
Run Code Online (Sandbox Code Playgroud)

结果如下:

               j                
????????????????????????????????
 {"dog": "cat", "frog": "frat"}
(1 row)
Run Code Online (Sandbox Code Playgroud)

您还可以直接对数据执行操作:

sql> select :'content'::jsonb -> 'dog';
 ?column? 
??????????
 "cat"
(1 row)
Run Code Online (Sandbox Code Playgroud)

在幕后这刚刚嵌入SQL中的JSON,但它是一个很大整洁,让PSQL进行插值本身.

  • ^这是金子。在不到5分钟的时间内将26000条记录导入到我的数据库中。没有一个步骤花费了超过一秒钟的时间。 (2认同)
  • 很棒的功能。“type”相当于 Windows 中的“cat”。 (2认同)

use*_*316 21

在接近大数据的情况下,从文件导入 json 的最有效方法似乎不是从文件导入单个 json 而是单列 csv:一行 json 的列表:

数据.json.csv:

{"id": 23635,"name": "Jerry Green","comment": "Imported from facebook."}
{"id": 23636,"name": "John Wayne","comment": "Imported from facebook."}
Run Code Online (Sandbox Code Playgroud)

然后,在 psql 下:

create table t ( j jsonb )
\copy t from 'd:\path\data.json.csv'
Run Code Online (Sandbox Code Playgroud)

每个 json(行)一条记录将被添加到 t 表中。

"\copy from" 导入是为 csv 进行的,因此逐行加载数据。因此,每行读取一个 json 而不是稍后拆分的单个 json 数组,将不会使用任何中间表。

如果您的输入 json 文件太大,您将不太可能达到最大输入行大小限制

因此,我会首先将您的输入转换为单列 csv,然后使用复制命令将其导入。


小智 9

您可以使用spyql。运行以下命令将生成可以通过管道传输到 psql 的 INSERT 语句:

$ jq -c .[] customers.json | spyql -Otable=customer "SELECT json->id, json->name, json->comment FROM json TO sql"
INSERT INTO "customer"("id","name","comment") VALUES (23635,'Jerry Green','Imported from facebook.'),(23636,'John Wayne','Imported from facebook.');
Run Code Online (Sandbox Code Playgroud)

jq用于将json数组转换为json行(每行1个json对象),然后spyql负责将json行转换为INSERT语句。

将数据导入 PostgreSQL:

$ jq -c .[] customers.json | spyql -Otable=customer "SELECT json->id, json->name, json->comment FROM json TO sql" | psql  -U your_user_name -h your_host your_database
Run Code Online (Sandbox Code Playgroud)

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