更改 DOMAIN 中的 CHECK 约束

问题描述 投票:0回答:2

有没有办法修改 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
,因为它使参数和列的意图更加清晰。

postgresql constraints ddl sql-domain
2个回答
1
投票

使用

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
。当新的约束添加到域中时,所有 使用该域的列将根据新添加的进行检查 约束。 [...]

由于您只允许附加值,因此任何现有列都不会发生冲突。


0
投票

我今天需要更改这个域名,进行了搜索......并在几年前遇到了这个问题。下面是一个更新的示例,其中包含一些注释。可能会帮助别人,或者可能会帮助我未来几年的未来......

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).
© www.soinside.com 2019 - 2024. All rights reserved.