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进行插值本身.
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的作者。
| 归档时间: |
|
| 查看次数: |
32958 次 |
| 最近记录: |