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
我知道这可以通过将产品提取到具有订单外键的单独产品表来完成.但我想知道在单个JSON列中是否可以实现这一点,因此在设计数据库模式时我可以牢记这一点.
解决方法
所以我问
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的致谢.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。