2014-11-25 3 views
0

Я попытался найти это в Интернете, и я просто ничего не могу найти.Ограничить ключи json в Postgres

У меня есть столбец в базе данных PostgreSQL типа JSON. У меня также есть таблица в базе данных, которая означает, что допустимые имена ключей могут использоваться в этом объекте JSON.

Примером может служить, если я хотел JSON выглядеть следующим образом: { "key":"value", "key2":"value" }, key и key2 должны быть записи в таблице действительные ключи для того, чтобы это было вставленные, в противном случае это нарушило бы ограничение. Я использую их в проекте C#, поэтому я мог бы, вероятно, проверить код, который я также буду делать, но я также хочу, чтобы кто-то просто не создал строку через pgAdmin.

Любые идеи?

+0

Вы ищете ограничение внешнего ключа, который не поддерживается для JSON (или XML или hstore). Разве вы не можете использовать обычный столбец с определенным внешним ключом? Если JSON содержит только одно значение, я все равно не вижу его преимуществ. –

+0

Я отредактировал, чтобы показать более одного ключа, что возможно. Одним из примеров был только один пример. – GBreen12

+0

Вы можете это сделать, но вам придется написать триггер. Если у вас установлена ​​v8 в вашей БД, это не будет так сложно. –

ответ

0

Используйте триггер для вставки и обновите его, если RAISE исключение, если база данных находится в противоречивом состоянии.

CREATE TABLE t1 (
    value json 
); 
CREATE TABLE t2 (
    valid_key text 
); 

CREATE FUNCTION check_t1_val_integrity() RETURNS trigger AS $func$ 
    DECLARE 
     valid_key_count integer; 
    BEGIN 
     -- Count keys from NEW, not present in t2 
     SELECT 
     count(*) 
     FROM 
     json_each(NEW.value) AS v(key,value) 
     LEFT JOIN t2 ON t2.valid_key = v.key 
     WHERE 
     t2.valid_key IS NULL 
     INTO 
     valid_key_count; 

     -- If we found some key not present in t2, then raise exception 
     IF valid_key_count > 0 THEN 
      RAISE EXCEPTION 'value not valid'; 
     END IF; 

     RETURN NEW; 
    END; 
$func$ LANGUAGE plpgsql; 

CREATE TRIGGER check_t1_val_integrity_trigger BEFORE INSERT OR UPDATE ON t1 
    FOR EACH ROW EXECUTE PROCEDURE check_t1_val_integrity(); 

Вот тесты:

INSERT INTO t2 (valid_key) VALUES(('a', ('b')); 

-- should work well 
INSERT INTO t1 (value) VALUES(
    ('{"a":"a"}'::json, ('{"b":"b"}'::json), ('{"a":"a","b":"b"}'::json) 
); 

-- should raise exception 
INSERT INTO t1 (value) VALUES(
    ('{"a":"a", "c":"c"}'::json 
); 
Смежные вопросы