我想验证postgres json字段,以便json中数组中的每个项都包含某些属性。例如,假设我有一个json字段,其中包含一个对象数组contacts
,我希望contacts
中的每个对象始终具有name
和phone
属性。如下 -
{
"contacts": [
{ "name": "a", "phone": "123" },
{ "name": "b", "phone": "456" }
]
}
是否有内置的方法来验证这一点,以便在插入/更新时始终保持此格式?
答案 0 :(得分:1)
如果json文档具有刚性结构,最好将此数据保存在常规表中。我假设对象包含许多密钥,包括一些必须的密钥。
以下函数检查json数组中的每个对象(第一个参数)是否包含所有数组字符串作为顶级键(第二个参数)。
create or replace function jsonb_has_keys(jsonb, text[])
returns boolean language sql as $$
select bool_and(value ?& $2)
from jsonb_array_elements($1)
$$;
在检查约束中使用该函数,例如:
create table test(
data jsonb check (jsonb_has_keys(data->'contacts', array['name', 'phone']))
);
insert into test values
('{
"contacts": [
{ "name": "a", "phone": "123" },
{ "name": "b", "tel": "456" }
]
}'::jsonb);
ERROR: new row for relation "test" violates check constraint "test_data_check"
DETAIL: Failing row contains ({"contacts": [{"name": "a", "phone": "123"}, {"tel": "456", "nam...).