有没有办法修改 Postgres 13.4 中现有
DOMAIN
约束的详细信息?
我一直在尝试并检查文档,并怀疑答案是:“不。
DROP
约束(或域和约束?),然后重建它。”
这很尴尬,因为我的字段和函数已经使用了约束,所以我还必须使用一些级联的项目
DROP
和CREATE
。我可以做到,但是有点复杂。
作为示例,我有一个像这样的简单域列表:
DROP DOMAIN IF EXISTS domains.user_name;
CREATE DOMAIN domains.user_name AS
citext
NOT NULL
CONSTRAINT user_name_legal_values
CHECK(
VALUE IN (
'postgres',
'dbadmin',
'user_bender',
'user_cleanup',
'user_domo_pull'
)
);
COMMENT ON DOMAIN domains.user_name IS
'Valid user_name role names.';
我想通过再插入一个名称来更改
VALUE IN
中的 CHECK
列表:'user_analytics'
。
这是否可以在不删除和重建域、约束或两者的情况下实现?
如果不是,我可以进行级联删除和重建,并预计未来
DOMAIN
不是处理此类事情的正确工具。我总是可以使用一个小的查找表来代替。我只是喜欢 DOMAIN
,因为它使参数和列的意图更加清晰。
ALTER DOMAIN
。删除旧的约束并添加新的约束。您不能在一个命令中同时执行这两项操作(与 ALTER TABLE
不同):
ALTER DOMAIN user_name DROP CONSTRAINT user_name_legal_values;
ALTER DOMAIN user_name ADD CONSTRAINT user_name_legal_values CHECK(
VALUE IN (
'postgres',
'dbadmin',
'user_analytics',
'user_bender',
'user_cleanup',
'user_domo_pull'
));
ADD domain_constraint [ NOT VALID ]
此形式使用与以下相同的语法向域添加新的约束
。当新的约束添加到域中时,所有 使用该域的列将根据新添加的进行检查 约束。 [...]CREATE DOMAIN
由于您只允许附加值,因此任何现有列都不会发生冲突。
我今天需要更改这个域名,进行了搜索......并在几年前遇到了这个问题。下面是一个更新的示例,其中包含一些注释。可能会帮助别人,或者可能会帮助我未来几年的未来......
ALTER DOMAIN domains.user_name
DROP CONSTRAINT IF EXISTS user_name_legal_values; -- Clear the old definition.
ALTER DOMAIN domains.user_name
ADD CONSTRAINT user_name_legal_values-- Set the updated definition
CHECK(
VALUE IN (
'rds_super',
'rdsadmin',
'user_admin',
'user_analytics',
'user_backup',
'user_bender',
'user_change_structure',
'user_cleanup',
'user_dba_task',
'user_domo_pull',
'user_duck',
'user_iceberg_remote',
'user_iceberg',
'user_leviathan',
'user_listener',
'user_push',
'user_quick',
'user_reporting',
'user_rest',
'user_saws',
'user_sonar')
) NOT VALID;
/*
NOT VALID goes down here, after the constraint definition.
NOT VALID requires a heavy lock, which *may* lead to a wait:
https://dba.stackexchange.com/questions/268301/why-is-add-constraint-not-valid-taking-a-long-time
As of PG 16.1, NOT VALID is needed here to avoid an automatic error from PG, based
on a field dependency check.
*/
-- Shouldn't need to validate the rule now, as Erwin pointed out originally.
-- Still, here's the syntax, and the outcome that I get:
ALTER DOMAIN domains.user_name
VALIDATE CONSTRAINT user_name_legal_values; -- If run, rechecks *entire* table.
-- ERROR: cannot alter type "user_name" because column "test_case.run_as" uses it. 0.000 seconds. (Line 43).