2016-08-30 192 views
4

比如我有一个文件customers.json这是一个对象(严格的形成)的数组,这是很普通的(没有嵌套对象)这样的(什么是重要的:它已经包括IDS):如何将JSON文件导入PostgreSQL?

[ 
    { 
    "id": 23635, 
    "name": "Jerry Green", 
    "comment": "Imported from facebook." 
    }, 
    { 
    "id": 23636, 
    "name": "John Wayne", 
    "comment": "Imported from facebook." 
    } 
] 

我想要将它们全部导入到我的postgres数据库中,并放入表customers

我发现了一些非常困难的方法,当我应该将它作为json-typed列导入到像imported_json这样的表和列名为data的列中,然后使用sql来获取这些值并将其插入到真实表中。

但是,有没有简单的方法导入JSON到Postgres没有触及SQL?

+0

”*没有触及sql *“否。与说SQL的关系数据库进行交互的唯一方式就是SQL。 –

+0

@a_horse_with_no_name哦...我很确定,然后我可以简单地将我的JSON转换为SQL查询。我会研究:) –

回答

13

您可以将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; 

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


以上假设表定义是这样的:

create table customer 
(
    id  integer primary key, 
    name  text not null, 
    comment text 
); 

如果数据为文件提供的,你需要首先把该文件到一些数据库中的表。例如:

create unlogged table customer_import (doc json); 

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

\copy customer_import from 'customers.json' .... 

然后你可以使用上面的语句,只是删除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; 
+0

我感谢你的帮助,但我发现我更好地将我的JSON转换为SQL(在我的情况下是红宝石)。然后只需使用psql命令导入sql。这比用sql解析json对象更容易:) Btw thx。 –

3

原来有一种简单的方法可以使用命令行psql工具将多行JSON对象导入到postgres数据库的JSON列中,而无需将JSON明确嵌入到SQL语句中。该技术记录在postgresql docs中,但它有点隐藏。

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

{ 
    "dog": "cat", 
    "frog": "frat" 
} 

我们可以使用下面的SQL将其加载到一个临时表:

# \set content `cat /tmp/test.json` 
# create temp table t (j jsonb); 
# insert into t values (:'content'); 
# select * from t; 

其给出结果:

   j     
──────────────────────────────── 
{"dog": "cat", "frog": "frat"} 
(1 row) 

您还可以执行的操作直接在数据上:

# select :'content'::jsonb -> 'dog'; 
?column? 
────────── 
"cat" 
(1 row) 

下面这个只是在SQL中嵌入JSON,但让psql自己执行插值更加简单。 “

+1

^这是黄金。只需在不到5分钟的时间内将26000条记录导入我的数据库。没有一个步骤花了超过一秒钟。 – fgblomqvist