根据 Postgres 10 中 JSON 的特定值执行 UPSERT
Do UPSERT based on specific value of JSON in Postgres 10
我有一个 Postgres table messages
如下:
Column | Type | Collation | Nullable |
-----------+--------------------------+-----------+----------
id | integer | | not null |
message | jsonb | | |
date | timestamp with time zone | | not null |
id | message | date
1 | {"name":"alpha", "pos":"x"} | 2020-02-11 12:31:44.658667+00
2 | {"name":"bravo", "pos":"y"} | 2020-02-11 12:32:43.123678+00
3 | {"name":"charlie", "pos":"z"}| 2020-02-11 12:38:37.623535+00
我想做的是根据 name
键的值做一个 UPSERT 即,如果有一个具有相同 name
值的插入,那么另一个值 pos
被更新,否则创建一个新条目。
我做到了CREATE UNIQUE INDEX message_name ON messages((message->>'name'));
我在 Postgres 9.5+ 中找到了 INSERT ON CONFLICT,但我不明白如何使用唯一索引。
首先我不知道这是否是正确的方法,所以如果有更好的方法,我将不胜感激。
您需要从索引中重复表达式:
insert into messages (message)
values ('{"name":"alpha", "pos":"new pos"}')
on conflict ((message->>'name'))
do update
set message = jsonb_set(messages.message, '{pos}'::text[], excluded.message -> 'pos', true)
;
如果您在 JSON 中有更多的键并且想要替换(或添加)所有这些,您可以使用这个:
insert into messages (message)
values ('{"name":"alpha", "pos":"new pos", "some key": 42}')
on conflict ((message->>'name'))
do update
set message = messages.message || (excluded.message - 'name')
;
我有一个 Postgres table messages
如下:
Column | Type | Collation | Nullable |
-----------+--------------------------+-----------+----------
id | integer | | not null |
message | jsonb | | |
date | timestamp with time zone | | not null |
id | message | date
1 | {"name":"alpha", "pos":"x"} | 2020-02-11 12:31:44.658667+00
2 | {"name":"bravo", "pos":"y"} | 2020-02-11 12:32:43.123678+00
3 | {"name":"charlie", "pos":"z"}| 2020-02-11 12:38:37.623535+00
我想做的是根据 name
键的值做一个 UPSERT 即,如果有一个具有相同 name
值的插入,那么另一个值 pos
被更新,否则创建一个新条目。
我做到了CREATE UNIQUE INDEX message_name ON messages((message->>'name'));
我在 Postgres 9.5+ 中找到了 INSERT ON CONFLICT,但我不明白如何使用唯一索引。
首先我不知道这是否是正确的方法,所以如果有更好的方法,我将不胜感激。
您需要从索引中重复表达式:
insert into messages (message)
values ('{"name":"alpha", "pos":"new pos"}')
on conflict ((message->>'name'))
do update
set message = jsonb_set(messages.message, '{pos}'::text[], excluded.message -> 'pos', true)
;
如果您在 JSON 中有更多的键并且想要替换(或添加)所有这些,您可以使用这个:
insert into messages (message)
values ('{"name":"alpha", "pos":"new pos", "some key": 42}')
on conflict ((message->>'name'))
do update
set message = messages.message || (excluded.message - 'name')
;