【问题标题】:List constraints for all tables with different owners in PostgreSQL列出 PostgreSQL 中具有不同所有者的所有表的约束
【发布时间】:2013-05-30 07:54:01
【问题描述】:

我是否必须是关系的所有者才能访问信息架构中的约束相关数据?我测试了以下,看来我必须是所有者。

create schema rights_test;

create table rights_test.t1 (id int primary key);
create table rights_test.t2 (id int references rights_test.t1(id));

select  
        tc.constraint_name, 
        tc.constraint_schema || '.' || tc.table_name || '.' || kcu.column_name as physical_full_name,  
        tc.constraint_schema,
        tc.table_name, 
        kcu.column_name, 
        ccu.table_name as foreign_table_name, 
        ccu.column_name as foreign_column_name,
        tc.constraint_type
    from 
        information_schema.table_constraints as tc  
        join information_schema.key_column_usage as kcu on (tc.constraint_name = kcu.constraint_name and tc.table_name = kcu.table_name)
        join information_schema.constraint_column_usage as ccu on ccu.constraint_name = tc.constraint_name
    where 
        constraint_type in ('PRIMARY KEY','FOREIGN KEY')
        and tc.constraint_schema = 'rights_test'

/*
This will produce desired output:
t1_pkey;rights_test.t1.id;rights_test;t1;id;t1;id;PRIMARY KEY
t2_id_fkey;rights_test.t2.id;rights_test;t2;id;t1;id;FOREIGN KEY
*/

create user rights_test_role with password 'password';

grant all on rights_test.t1 to rights_test_role;
grant all on rights_test.t2 to rights_test_role;

/* Now login as rights_test_role and try the same constraint select.
   For rights_test_role it returns nothing although I've added ALL privileges
*/

如果我不是关系的所有者,还有其他方法可以获取相同的信息吗?

【问题讨论】:

    标签: postgresql postgresql-9.1


    【解决方案1】:

    并非所有与约束相关的数据都受到“保护”。您在查询中使用了三个关系:

    • table_constraints
    • key_column_usage
    • constraint_column_usage

    前两个不限,但constraint_column_usage的文档告诉你:

    视图 constraint_column_usage 标识当前数据库中由某个约束使用的所有列。 仅显示当前启用的角色拥有的表中包含的那些列。

    由于information_schema.constraint_column_usage是一个视图,你可以使用

    查看它的定义
    \d+ information_schema.constraint_column_usage
    

    在 psql 外壳中。结果乍一看很吓人,但实际上并没有那么糟糕。最有趣的事情——对于第一次测试——是最后一行的部分:

      WHERE pg_has_role(x.tblowner, 'USAGE'::text);
    

    如果您将定义粘贴到非所有者rights_test_role 打开的 psql shell 中并删除最后一行,您将获得所需的结果。这很好,因为这意味着基本元数据不受系统保护。因此,您可以剥离视图定义以仅包含您真正需要的部分。

    【讨论】:

    • \d+ 是你的朋友。
    【解决方案2】:

    尝试使用这个.. 给出所有约束名称和约束描述。

    • 外键
    • 检查
    • 主键
    • 独特

    喜欢:

    select conrelid::regclass AS table_from, conname, pg_get_constraintdef(c.oid)
    from   pg_constraint c
    join   pg_namespace n ON n.oid = c.connamespace
    where  contype in ('f', 'p','c','u') order by contype
    

    【讨论】:

      【解决方案3】:

      要列出关系约束,您可以使用下一个查询:

      SELECT
          tc.constraint_name, tc.table_name, kcu.column_name, 
          ccu.table_name AS foreign_table_name,
          ccu.column_name AS foreign_column_name 
      FROM 
          information_schema.table_constraints AS tc 
          JOIN information_schema.key_column_usage AS kcu
            ON tc.constraint_name = kcu.constraint_name
          JOIN information_schema.constraint_column_usage AS ccu
            ON ccu.constraint_name = tc.constraint_name
      WHERE constraint_type = 'FOREIGN KEY'
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-07-28
        • 1970-01-01
        • 2023-01-18
        • 1970-01-01
        • 1970-01-01
        • 2014-09-19
        • 2011-01-17
        • 2021-01-19
        相关资源
        最近更新 更多