CREATE TABLE TOTABLE (LIKE FROMTABLE INCLUDING INDEXES)
在复制模式时,是否有一种方法可以复制权限,或者我可以从“FROMTABLE”之后应用权限?
CREATE TABLE TOTABLE (LIKE FROMTABLE INCLUDING INDEXES)
在复制模式时,是否有一种方法可以复制权限,或者我可以从“FROMTABLE”之后应用权限?
在直接操作目录表时,一定要非常小心。通常建议仅使用DDL语句。目录表不适合由用户编写。如果搞砸了,您的DB集群可能会损坏到无法修复。你已经被警告了。
更新:事实证明,上述警告是非常正确的。这本来就是个坏主意。标准的GRANT
/REVOKE
命令(以及默认权限系统)也会在pg_shdepend
表中创建条目,以记录访问控制列表中提到的对象和角色之间的依赖关系(除了所有者,因为已经链接)。手册:
通过直接操作访问控制列表(关系的目录
pg_shdepend
记录数据库对象和共享对象(如角色)之间的依赖关系。这些信息使PostgreSQL能够确保在尝试删除它们之前,这些对象没有被引用。
relacl
)会导致依赖关系失去同步,这可能会在尝试稍后删除角色时导致“奇怪”的问题。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
强制转换操作会确定性地选择一个表,即使没有架构限定。详情请见:
如果其中一个表找不到,你会立即收到异常通知(regclass
的强制转换失败)。
如果未找到from_table
,@Robert的查询将愉快地将relacl
设置为NULL。
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
)。
可以使用以下命令将表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语句即可复制权限。