我有一个导入过程,它使用下面的代码复制表模式,然后用数据填充表。但是,它不会复制授予的角色。
CREATE TABLE TOTABLE (LIKE FROMTABLE INCLUDING INDEXES)
有没有办法可以在复制架构时复制权限,或者我可以在" FROMTABLE"之后应用权限?
答案 0 :(得分:3)
直接操作目录表时, 非常小心 。通常建议仅使用DDL语句。目录表不是由用户编写的。如果你搞砸了,你的数据库集群可能会被破坏而无法修复。你被警告了。
更新:原来,上述警告是完全正确的。这是一个糟糕的主意。标准GRANT
/ REVOKE
命令(以及default privilege system)也在pg_shdepend
表中创建条目以记住访问控制列表中提到的对象和角色之间的依赖关系(除了所有者,无论如何都是链接的)。 The manual:
目录
pg_shdepend
记录了之间的依赖关系 数据库对象和共享对象,例如角色。此信息 允许PostgreSQL确保之前未引用这些对象 试图删除它们。
通过直接操作访问控制列表(关系的relacl
),依赖关系会失去同步,这会在以后尝试删除角色时导致“奇怪”问题。
最近有一个discussion about "Copying Permissions" on pgsql-hackers(2016年11月),但尚未实施。
过时,请勿使用:
query presented by @Robert有一个错误(正如他所说):relname
不唯一。在同一db的多个模式中可以有任意数量的具有相同名称的表。修复:
UPDATE pg_class c_to
SET relacl = c_from.relacl
FROM pg_class c_from
WHERE c_from.oid = 'public.from_table'::regclass
AND c_to.oid = 'public.to_table'::regclass
对regclass
的强制转型确定性地选择一个表,即使没有架构资格。详细说明:
如果找不到其中一个表,则会立即收到异常(转换为regclass
失败)。
如果找不到relacl
,@ Robert的查询会很乐意将from_table
设置为NULL。
答案 1 :(得分:1)
有关postgresql中表的信息存储在pg_class
表中。包含表权限的字段为relacl
。
如下所示:
update pg_class set relacl = (select relacl from pg_class where relname = 'from_table') where relname='to_table';
请注意,pg_class
包含所有表的元数据 - 因此,如果多个表中存在同名表,您还应该注意确保使用正确的模式(relnamespace
)模式。