与 UPDATE 规则相比,postgres INSERT 规则中生成的 UUID 行为
Generated UUIDs behavior in postgres INSERT rule compared to the UPDATE rule
我有一个带有单个 table 的 postgres 数据库。这个 table 的主键是生成的 UUID。我正在尝试向该数据库添加一个日志记录 table,以便每当添加或删除一行时,日志记录 table 都会获得一个条目。我的 table 具有以下结构
CREATE TABLE configuration (
id uuid NOT NULL DEFAULT uuid_generate_v4(),
name text,
data json
);
我的日志记录 table 具有以下结构
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
);
现在,如果我在配置 table 中插入一个值,配置 table 和 configuration_log table 中的 UUID 是不同的。例如,插入查询
INSERT INTO configuration (name, data)
VALUES ('test', '{"property1":"value1"}')
结果是this... the UUID is c2b6ca9b-1771-404d-baae-ae2ec69785ac
in the configuration table whereas in the configuration_log table the result is this...UUID id 16109caa-dddc-4959-8054-0b9df6417406
但是,更新规则按预期工作。因此,如果我将更新查询写为
UPDATE "configuration"
SET "data" = '{"property1":"abcd"}'
WHERE "id" = 'c2b6ca9b-1771-404d-baae-ae2ec69785ac';
configuration_log table 得到正确的 UUID here 即 c2b6ca9b-1771-404d-baae-ae2ec69785ac
我在两个规则中都使用了 NEW.id
,所以我期待相同的行为。谁能指出我在这里可能做错了什么?
谢谢
这是另一个很好的例子,为什么 rules should be avoided
For any reference to NEW, the target list of the original query is searched for a corresponding entry. If found, that entry's expression replaces the reference.
所以 NEW.id
被替换为 uuid_generate_v4()
这解释了为什么您看到不同的值。
您应该将其重写为触发器。
顺便说一句:使用 jsonb
比 json
更可取,那么您还可以摆脱 json
列到 text
的(基本上不正确的)强制转换比较内容。
我有一个带有单个 table 的 postgres 数据库。这个 table 的主键是生成的 UUID。我正在尝试向该数据库添加一个日志记录 table,以便每当添加或删除一行时,日志记录 table 都会获得一个条目。我的 table 具有以下结构
CREATE TABLE configuration (
id uuid NOT NULL DEFAULT uuid_generate_v4(),
name text,
data json
);
我的日志记录 table 具有以下结构
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
);
现在,如果我在配置 table 中插入一个值,配置 table 和 configuration_log table 中的 UUID 是不同的。例如,插入查询
INSERT INTO configuration (name, data)
VALUES ('test', '{"property1":"value1"}')
结果是this... the UUID is c2b6ca9b-1771-404d-baae-ae2ec69785ac
in the configuration table whereas in the configuration_log table the result is this...UUID id 16109caa-dddc-4959-8054-0b9df6417406
但是,更新规则按预期工作。因此,如果我将更新查询写为
UPDATE "configuration"
SET "data" = '{"property1":"abcd"}'
WHERE "id" = 'c2b6ca9b-1771-404d-baae-ae2ec69785ac';
configuration_log table 得到正确的 UUID here 即 c2b6ca9b-1771-404d-baae-ae2ec69785ac
我在两个规则中都使用了 NEW.id
,所以我期待相同的行为。谁能指出我在这里可能做错了什么?
谢谢
这是另一个很好的例子,为什么 rules should be avoided
For any reference to NEW, the target list of the original query is searched for a corresponding entry. If found, that entry's expression replaces the reference.
所以 NEW.id
被替换为 uuid_generate_v4()
这解释了为什么您看到不同的值。
您应该将其重写为触发器。
顺便说一句:使用 jsonb
比 json
更可取,那么您还可以摆脱 json
列到 text
的(基本上不正确的)强制转换比较内容。