在PostgreSQL中,您是否可以将一个表的权限复制到另一个表?

7
我有一个导入过程,使用以下代码复制表架构,然后用数据填充表格。然而它没有复制授予的角色。
CREATE TABLE TOTABLE (LIKE FROMTABLE INCLUDING INDEXES)

在复制模式时,是否有一种方法可以复制权限,或者我可以从“FROMTABLE”之后应用权限?


1
通常情况下,如果您想要这样做,应该创建一个角色,将所需的权限分配给该角色,然后只需将权限授予新表中的该角色即可。 - Craig Ringer
可能是另一个问题的重复:PostgreSQL从另一张表复制权限 - luto
3个回答

9

在直接操作目录表时,一定要非常小心。通常建议仅使用DDL语句。目录表不适合由用户编写。如果搞砸了,您的DB集群可能会损坏到无法修复。你已经被警告了。

更新:事实证明,上述警告是非常正确的。这本来就是个坏主意。标准的GRANT/REVOKE命令(以及默认权限系统)也会在pg_shdepend表中创建条目,以记录访问控制列表中提到的对象和角色之间的依赖关系(除了所有者,因为已经链接)。手册:

目录pg_shdepend记录数据库对象和共享对象(如角色)之间的依赖关系。这些信息使PostgreSQL能够确保在尝试删除它们之前,这些对象没有被引用。

通过直接操作访问控制列表(关系的relacl)会导致依赖关系失去同步,这可能会在尝试稍后删除角色时导致“奇怪”的问题。
最近有一个关于“复制权限”的讨论(2016年11月),但尚未实现。
不完整的解决方案(不要使用!) @Robert提出的查询存在一个错误(如他所指出的):relname不是唯一的。可以在同一数据库的多个模式中有任意数量的具有相同名称的表。要修复:
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强制转换操作会确定性地选择一个表,即使没有架构限定。详情请见:

  • 如何加速在PostgreSQL表中计数行数?

  • 如果其中一个表找不到,你会立即收到异常通知(regclass的强制转换失败)。
    如果未找到from_table,@Robert的查询将愉快地将relacl设置为NULL。


2

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)。


0

可以使用以下命令将表DDL及其权限转储到文件中:

pg_dump --schema-only --table=my_old_table --schema=my_schema --dbname=my_db --file=my_old_table_ddl.sql ...

接下来,可以编辑my_old_table_ddl.sql以将old_table_name替换为new_table_name,并使用psql命令执行DLL。

只需执行GRANT语句即可复制权限。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接