PostgreSQL是否提供了对JSON数组的每个元素施加约束的任何符号/方法?
一个例子:
create table orders(data json);
insert into orders values ('
{
"order_id": 45,
"products": [
{
"product_id": 1,
"name": "Book"
},
{
"product_id": 2,
"name": "Painting"
}
]
}
');
我可以轻松地在order_id
字段上添加约束:
alter table orders add check ((data->>'order_id')::integer >= 1);
现在我需要对product_id
做同样的事情。我可以对个别数组项进行约束:
alter table orders add check ((data->'products'->0->>'product_id')::integer >= 1);
alter table orders add check ((data->'products'->1->>'product_id')::integer >= 1);
-- etc.
显然我正在寻找的是匹配任何JSON数组元素的某种通配符运算符:
alter table orders add check ((data->'products'->*->>'product_id')::integer >= 1);
-- ^ like this
我知道这可以通过将产品提取到具有products
外键的单独orders
表来完成。但我想知道在单个JSON列中是否可以实现这一点,因此在设计数据库模式时我可以牢记这一点。
答案 0 :(得分:3)
所以我问this question on PostgreSQL mailing list,suggested by Craig Ringer,我得到了答案。
简而言之,解决方案是编写一个将JSON数组实现为PostgreSQL数组的过程:
create function data_product_ids(JSON) returns integer[] immutable as $$
select array_agg((a->>'product_id')::integer) from
json_array_elements($1->'products') as a $$ language sql ;
并在CHECK
陈述中使用该程序:
alter table orders add check (1 <= ALL(data_product_ids(data)));
有关其工作原理的详细信息,请the answer on PostgreSQL mailing list。致Joel Hoffman的信用。
答案 1 :(得分:0)
来自JSON for Postgres的一位开发人员
路径内容不支持通配符。