Stack溢出Q&A 在PostgreSQL中同时修改所有表的所有者描述了一些将表和其他对象更改为特定用户的巧妙方法,它运行得很顺利,但是所有建议似乎都忽略了我创建的函数。
是否有一种相当简单的方法来重置数据库中所有对象的所有者,包括函数?用手做是非常不可取的。
发布于 2011-12-24 19:58:27
嗯,我没有找到一个单步进程,但是这处理了我可以在数据库中看到的所有对象:
update pg_class
SET relowner = (SELECT oid FROM pg_roles WHERE rolname = 'foo')
where relnamespace = (select oid
from pg_namespace
where nspname = 'public'
limit 1);
update pg_proc
set proowner = (select oid from pg_roles where rolname = 'foo')
where pronamespace = (select oid
from pg_namespace
where nspname = 'public'
limit 1);发布于 2011-12-24 22:02:59
如果您确切地知道自己在做什么,那么您只应该直接操作系统目录。它可能会产生意想不到的副作用。或者,您可以损坏数据库(或整个数据库集群),无法修复。
杰里米的回答,虽然基本上做到了这一点,但对一般公众来说是不可取的。它无条件地更改架构中的所有函数。您确定其他模块没有影响系统功能或安装功能吗?
更改已经属于指定所有者的函数的所有者也是没有意义的。
首先,检查重新分配是否适合您:
更改数据库角色拥有的数据库对象的所有权
您必须列出所有要显式不承认的角色。但它也重新分配了职能。
若要将给定架构中的所有函数(不包括其他对象)分配给新所有者(可选地不管以前的所有者):
SELECT string_agg('ALTER FUNCTION '|| oid::regprocedure || ' OWNER TO foo;', E'\n') AS ddl
FROM pg_catalog.pg_proc
WHERE pronamespace = 'public'::regnamespace
-- AND proowner <> 'foo'::regrole
-- AND proname ~~ 'f_%'这将生成规范的SQL commandsALTER函数。以更改所有函数(在指定的架构中)。在执行之前先检查命令--一次一个一个地执行或全部执行:
ALTER FUNCTION public.bar(text, text) OWNER TO foo;
ALTER FUNCTION public.foo(x integer) OWNER TO foo;
...对regprocedure的强制转换生成一个有效的函数名,其中参数在必要时为双引号,在必要时为当前search_path提供模式限定。
同时为了简单起见也使用了对象标识符类型regnamespace和regrole。
我添加了一些注释的WHERE子句,您可能希望使用这些子句来筛选结果。
您可以将所有这些都放入DO语句或类似于这个相关答案中演示的函数中:
对于Postgres 9.4或更高版本:
SELECT string_agg('ALTER FUNCTION ' || oid::regprocedure || ' OWNER TO foo;', E'\n') AS ddl
FROM pg_catalog.pg_proc p
JOIN pg_catalog.pg_namespace n ON n.oid = p.pronamespace
WHERE n.nspname = 'public'
-- AND p.proowner <> (SELECT oid FROM pg_roles WHERE rolname = 'foo')
-- AND p.proname ~~ 'f_%'聚合函数string_agg()需要PostgreSQL 9.0或更高版本。在旧版本中,用array_agg()和array_to_string()代替。
发布于 2021-06-16 04:25:03
只需转储数据库模式,然后使用GnSa或"Grep n Sed away“。
pg_dump DBNAME -s | grep -E "OWNER TO" | sed -E "s/(OWNER TO )ownerA/\1ownerB/" | psql DBNAMEhttps://dba.stackexchange.com/questions/9708
复制相似问题