【问题标题】:Populate multiple tables from a single JSON object with json_populate_recordset使用 json_populate_recordset 从单个 JSON 对象填充多个表
【发布时间】:2014-11-20 15:35:22
【问题描述】:

我已经阅读了related question,但与用户 kenthewala 不同,我想将一组 JSON 对象放入数据库中。

我的 JSON 文件如下所示:

{
"tablename_a":[{"a_id":1,"b_id":2,"c_id":3},
 {"a_id":2,"b_id":51,"c_id":3}],
"tablename_b":[{"b_id":2,"name":"John Doe", "z_id":123},
 {"b_id":51,"name":"Mary Ann", "z_id":412}],
"tablename_c":[{"c_id":3, "OS type":"Windows 7"}],
"tablename_z":[{"z_id":123, "Whatever":"Something"},
{"z_id":123, "Whatever":"Something else"}]
}

数据库中已存在具有相应名称的表。

在我想象的伪代码中

for each key in JSON_FILE as tbl_name
(
  insert into tbl_name select * from json_populate_recordset
  (
    null::tbl_name, 'content of tbl_name'
  )
)

但我不确定,如何实现这一点。

我正在使用 PostgreSQL 9.3.5(如果有帮助的话,还有 PHP 5.3.3)。

表结构类似于 JSON 文件(因为我最初从数据库中导出了 JSON):

create table tablename_a (a_id integer, b_id integer, c_id integer);
create table tablename_b (b_id integer, name text, z_id integer);

等等。

【问题讨论】:

  • 至少一个表的实际表定义会很好。 CREATE TABLE ...。并且总是你的 Postgres 版本。
  • 你是对的,谢谢你的提示!相应地更改了我的帖子。

标签: sql json postgresql import common-table-expression


【解决方案1】:

3 个步骤:

  1. -> 的 JSON 对象的访问字段。
  2. 使用json_populate_recordset() 从记录的 JSON 数组创建派生表。
  3. 分解INSERT 命令的行类型。

要重用所有表的输入值,请将其包装在data-modifying CTEs

WITH input AS (
   SELECT '{
      "tablename_a":[{"a_id":1,"b_id":2,"c_id":3},
       {"a_id":2,"b_id":51,"c_id":3}],
      "tablename_b":[{"b_id":2,"name":"John Doe", "z_id":123},
       {"b_id":51,"name":"Mary Ann", "z_id":412}],
      "tablename_c":[{"c_id":3, "OS type":"Windows 7"}],
      "tablename_z":[{"z_id":123, "Whatever":"Something"},
      {"z_id":123, "Whatever":"Something else"}]
      }'::json AS j
   )
,  a AS (
   INSERT INTO tablename_a
   SELECT t.*
   FROM   input i
        , json_populate_recordset(NULL::tablename_a, i.j->'tablename_a') t
   )
,  b AS (
   INSERT INTO tablename_b
   SELECT t.*
   FROM   input i
        , json_populate_recordset(NULL::tablename_b, i.j->'tablename_b') t
   )
   -- ... more ...
INSERT INTO tablename_z
SELECT t.*
FROM   input i
     , json_populate_recordset(NULL::tablename_z, i.j->'tablename_z') t
;

SQL Fiddle.

使用隐式JOIN LATERAL。相关:

【讨论】:

  • 谢谢,我目前遇到了语法错误,但您引导我走向正确的方向!但我必须承认,我曾希望,有一种方法可以以某种方式将表名提取为某种变量,因此您不必手动编写每个 SELECT 语句。
  • @Picl:这也是可能的,但您需要动态 SQL。我已经发布了许多相关的答案。 Try a search. 我怀疑如果你有一个给定的结构,额外的努力是否值得。至于语法错误:添加的小提琴证明我的代码有效。
  • 问题是我想太多了^^。我以为你已经缩写了你的代码,因为它只是一个例子。因此,我用'z AS(...);'包围了最后一个插入语句就像之前的其他陈述一样,这显然是错误的方式。由于有很多表,我可能并不总是想一次更新所有表,我想,我会尝试采用动态方式。感谢您的帮助和提供的链接!
猜你喜欢
  • 2019-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-19
  • 2019-01-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多