用json数据同步postgres表

时间:2018-12-01 19:18:11

标签: sql postgresql

我有一个端点来获取json格式的信息

[
  {
    id: 123,
    name: 'a name',
    code: '123SDF',
    category: 'some category'
  },
  {
    id: 234,
    name: 'a another name',
    code: '234SDF',
    category: 'some category'
  },
  etc...
]

我需要将其与本地表同步。我只是截断并添加,但现在我需要更新或插入。原因是因为我正在向本地表添加列。本地表包含以下列:

id,
name,
code,
category,
template

所以我不能再截断,因为我会丢失模板字段。我可以运行什么查询,以便在找到ID时更新该查询,否则为我的其他字段插入null?

json数据和我的表的ID都相同。

1 个答案:

答案 0 :(得分:1)

我想有多种方法可以做到这一点。您可以将表配置为使id列唯一,然后在该行已经存在时使用ON CONFLICT子句进行更新。

但是,这是一种无需更改表内容即可实现的方法。

  1. 转换数据(使事情变得更容易)
  2. 进行更新,找出哪些ID已更新
  3. 对未更新的ID进行INSERT

设置:

CREATE TABLE t (id INTEGER, name TEXT, code TEXT, category TEXT, template TEXT);

INSERT INTO t VALUES (123, 'a name', 'a code', 'a cat', 'a template');

可怜的人的烦恼:

WITH
  source_data AS (
    SELECT (j->>'id')::INTEGER AS id,
           j->>'name' AS name,
           j->>'code' AS code,
           j->>'category' AS category
    FROM JSON_ARRAY_ELEMENTS(
      '[
        {
        "id": 123,
        "name": "a name",
        "code": "123SDF",
        "category": "some category"
        },
        {
        "id": 234,
        "name": "a another name",
        "code": "234SDF",
        "category": "some category"
        }
      ]'::JSON) j
  ),
  updated AS (
    UPDATE t
    SET name = s.name,
        code = s.code,
        category = s.category
    FROM source_data s
    WHERE t.id = s.id
    RETURNING t.id
  )
INSERT INTO t
SELECT id, name, code, category, NULL
FROM source_data s
WHERE s.id NOT IN (SELECT id FROM updated);

在置顶后执行SELECT * FROM t的结果:

| id  | name           | code   | category      | template   |
| --- | -------------- | ------ | ------------- | ---------- |
| 123 | a name         | 123SDF | some category | a template |
| 234 | a another name | 234SDF | some category |            |

您可以看到现有记录的模板值未被覆盖。