Сгенерированное поведение UUID в правиле postgres INSERT по сравнению с правилом UPDATE - PullRequest
0 голосов
/ 16 марта 2020

У меня есть postgres база данных с одной таблицей. Первичным ключом этой таблицы является сгенерированный UUID. Я пытаюсь добавить таблицу регистрации в эту базу данных так, чтобы при добавлении или удалении строки таблица регистрации получала запись. Моя таблица имеет следующую структуру

CREATE TABLE configuration (
     id    uuid NOT NULL DEFAULT uuid_generate_v4(),
     name  text,
     data  json 
);

Моя таблица регистрации имеет следующую структуру

CREATE TABLE configuration_log (
    configuration_id         uuid,
    new_configuration_data   json,
    old_configuration_data   json,
    "user"                   text,
    time                     timestamp
);

Я добавил следующие правила:

CREATE OR REPLACE RULE log_configuration_insert AS ON INSERT TO "configuration"
       DO INSERT INTO configuration_log VALUES (
          NEW.id,
          NEW.data,
          '{}',
          current_user,
          current_timestamp
       );

CREATE OR REPLACE RULE log_configuration_update AS ON UPDATE TO "configuration"
      WHERE NEW.data::json::text != OLD.data::json::text
      DO INSERT INTO configuration_log VALUES (
          NEW.id,
          NEW.data,
          OLD.data,
          current_user,
          current_timestamp
      );

Теперь, если Я вставляю значение в таблицу конфигурации, UUID в таблицу конфигурации и таблицу configuration_log различаются. Например, запрос вставки

INSERT INTO configuration (name, data) 
       VALUES ('test', '{"property1":"value1"}')

Результат this ... UUID равен c2b6ca9b-1771-404d-baae-ae2ec69785ac в таблице конфигурации, тогда как в таблице configuration_log результат равен this ... идентификатор UUID 16109caa-dddc-4959-8054-0b9df6417406

Однако правило обновления работает, как и ожидалось. Поэтому, если я напишу запрос на обновление в виде

UPDATE "configuration" 
    SET "data" = '{"property1":"abcd"}' 
    WHERE "id" = 'c2b6ca9b-1771-404d-baae-ae2ec69785ac';

Таблица configuration_log получит правильный UUID, как показано здесь , т.е. c2b6ca9b-1771-404d-baae-ae2ec69785ac

Я использую NEW.id в оба правила, поэтому я ожидал того же поведения. Кто-нибудь может указать, что я могу делать здесь не так?

Спасибо

1 Ответ

1 голос
/ 16 марта 2020

Это еще один хороший пример того, почему правил следует избегать

Цитата из руководства :

Для любой ссылки на NEW В целевом списке исходного запроса выполняется поиск соответствующей записи. Если найдено, то выражение записи заменяет ссылку .

Так что NEW.id заменяется на uuid_generate_v4(), что объясняет, почему вы видите другое значение.

Вы должны переписать это на триггер.


Кстати: использование jsonb предпочтительнее, чем json, тогда вы также можете избавиться от (по существу неправильного) приведения столбца json к text для сравнения содержимого.

...