在PostgreSQL中同时修改所有表上的OWNER

Kai*_*Kai 384 postgresql

如何修改PostgreSQL数据库中所有表的所有者?

我试过,ALTER TABLE * OWNER TO new_owner但它不支持星号语法.

Try*_*tøl 521

您可以使用该REASSIGN OWNED命令.

概要:

REASSIGN OWNED BY old_role [, ...] TO new_role
Run Code Online (Sandbox Code Playgroud)

这会将所有拥有的对象更改old_role为新角色.您不必考虑用户拥有的对象类型,它们都将被更改.请注意,它仅适用于单个数据库中的对象.它也不会改变数据库本身的所有者.

它可以回到至少8.2.他们的在线文档只能追溯到很久以前.

  • 这似乎不适用于用户postgres,即使我连接到我创建的数据库(即不是系统数据库),它说:错误:无法重新分配角色postgres拥有的对象的所有权,因为数据库需要它们系统 (37认同)
  • 更好的解决方案.这应该是公认的答案 (20认同)
  • 正如@thnee报道的那样,REASSIGN影响数据库中的所有对象,并且它不区分用户定义的对象和系统对象,因此如果有任何扩展具有自己的表,则它不适用于postgres.我仍然更喜欢(+1)这个优雅的选项,即使它对我没什么帮助(我的数据库以前由postgres拥有). (13认同)
  • 需要明确的是,此命令仅适用于您当前连接的数据库.如果old_role拥有多个数据库中的对象,则应在每个数据库中连接并运行此命令 (5认同)
  • 这似乎不适用于通过AWS RDS托管的postgres.我收到这个错误"拒绝重新分配对象的权限",这个链接暗示了原因:"似乎'重新分配拥有'的唯一方法是作为超级用户(与文档相矛盾),这是无法访问的在RDS.' http://www.postgresql-archive.org/REASSIGN-OWNED-simply-doesn-t-work-td5987901.html (4认同)
  • 听起来您正在尝试重新分配 postgresql 内部对象的所有权,例如 pg_* 表/视图。 (2认同)

Ale*_*oto 435

REASSIGN OWNED命令

注意:正如@trygvis 在下面的答案中提到的,该REASSIGN OWNED命令至少从版本8.2开始可用,并且是一种更容易的方法.


由于您要更改所有表的所有权,因此您可能也需要视图和序列.这是我做的:

表:

for tbl in `psql -qAt -c "select tablename from pg_tables where schemaname = 'public';" YOUR_DB` ; do  psql -c "alter table \"$tbl\" owner to NEW_OWNER" YOUR_DB ; done
Run Code Online (Sandbox Code Playgroud)

序列:

for tbl in `psql -qAt -c "select sequence_name from information_schema.sequences where sequence_schema = 'public';" YOUR_DB` ; do  psql -c "alter sequence \"$tbl\" owner to NEW_OWNER" YOUR_DB ; done
Run Code Online (Sandbox Code Playgroud)

浏览次数:

for tbl in `psql -qAt -c "select table_name from information_schema.views where table_schema = 'public';" YOUR_DB` ; do  psql -c "alter view \"$tbl\" owner to NEW_OWNER" YOUR_DB ; done
Run Code Online (Sandbox Code Playgroud)

由于alter语句对于所有三个语句都相同,所以你可能会稍微一点.


  • REASSIGN OWNED BY对postgres拥有的对象不起作用. (60认同)
  • 此外,REASSIGN OWNED实际上会影响旧角色拥有的所有数据库的所有权(请参阅:http://www.postgresql.org/docs/9.3/static/sql-reassign-owned.html).因此,如果您只想更改单个数据库的所有权,请注意! (19认同)
  • +1谢谢Alex.我根据你的答案创建了一个小的bash脚本,可以在https://gist.github.com/2482969上找到 (10认同)
  • 请参阅@trygvis最近的回答.到目前为止最简单的答案:`由old_role [,...]重新配置为new_role` (10认同)
  • 基于@gingerlime脚本,bspkrs(找不到他的名字)创建了一个也改变了功能:[https://gist.github.com/bspkrs/b997ed7f1eb1268f3403 ](https://gist.github.com/bspkrs/b997ed7f1eb1268f3403) (3认同)

rkj*_*rkj 179

这个:http://archives.postgresql.org/pgsql-bugs/2007-10/msg00234.php也是一个很好的快速解决方案,适用于一个数据库中的多个模式:

SELECT 'ALTER TABLE '|| schemaname || '.' || tablename ||' OWNER TO my_new_owner;'
FROM pg_tables WHERE NOT schemaname IN ('pg_catalog', 'information_schema')
ORDER BY schemaname, tablename;
Run Code Online (Sandbox Code Playgroud)

序列

SELECT 'ALTER SEQUENCE '|| sequence_schema || '.' || sequence_name ||' OWNER TO my_new_owner;'
FROM information_schema.sequences WHERE NOT sequence_schema IN ('pg_catalog', 'information_schema')
ORDER BY sequence_schema, sequence_name;
Run Code Online (Sandbox Code Playgroud)

查看

SELECT 'ALTER VIEW '|| table_schema || '.' || table_name ||' OWNER TO my_new_owner;'
FROM information_schema.views WHERE NOT table_schema IN ('pg_catalog', 'information_schema')
ORDER BY table_schema, table_name;
Run Code Online (Sandbox Code Playgroud)

物化观点

基于这个答案

SELECT 'ALTER TABLE '|| oid::regclass::text ||' OWNER TO my_new_owner;'
FROM pg_class WHERE relkind = 'm'
ORDER BY oid;
Run Code Online (Sandbox Code Playgroud)

这将生成所有必需的ALTER TABLE/ ALTER SEQUENCE/ ALTER VIEW语句,复制它们并将它们粘贴回plsql以运行它们.

通过执行以下操作检查psql中的工作:

\dt *.*
\ds *.*
\dv *.*
Run Code Online (Sandbox Code Playgroud)

  • 一个很好的解决方案! (3认同)
  • 我更喜欢这个答案,因为(1)它可以在psql或pgAdmin(2)中完成,它可以让你轻松地看到你要改变的对象.我还使用了类似的http://stackoverflow.com/questions/22803096/how-to-alter-owner-of-a-function-in-postgres,但是对于函数. (2认同)

Joh*_*lin 41

如果你想在一个sql语句中执行它,你需要定义一个exec()函数,如http://wiki.postgresql.org/wiki/Dynamic_DDL中所述.

CREATE FUNCTION exec(text) returns text language plpgsql volatile
  AS $f$
    BEGIN
      EXECUTE $1;
      RETURN $1;
    END;
$f$;
Run Code Online (Sandbox Code Playgroud)

然后您可以执行此查询,它将更改表,序列和视图的所有者:

SELECT exec('ALTER TABLE ' || quote_ident(s.nspname) || '.' ||
            quote_ident(s.relname) || ' OWNER TO $NEWUSER')
  FROM (SELECT nspname, relname
          FROM pg_class c JOIN pg_namespace n ON (c.relnamespace = n.oid) 
         WHERE nspname NOT LIKE E'pg\\_%' AND 
               nspname <> 'information_schema' AND 
               relkind IN ('r','S','v') ORDER BY relkind = 'S') s;
Run Code Online (Sandbox Code Playgroud)

$ NEWUSER是新所有者的postgresql新名称.

在大多数情况下,您需要成为超级用户才能执行此操作.您可以通过将所有者从您自己的用户更改为您所属的角色组来避免这种情况.

感谢#postgresql上的RhodiumToad帮助解决这个问题.

  • 这会更加有用,因为它会更改整个模式的所有权,包括功能,索引,序列等。谢谢! (2认同)

ebi*_*ood 29

如果当前所有者不是 postgres,您可以使用以下命令:

REASSIGN OWNED BY old_role [, ...] TO new_role
Run Code Online (Sandbox Code Playgroud)

但是如果当前所有者是 postgres,你肯定会得到错误,所以你必须使用 @dvanrensburg 答案,但如果你想在同一个 sql 中执行命令,请根据需要使用这些命令:

数据库

ALTER DATABASE target_database OWNER TO new_onwer;
Run Code Online (Sandbox Code Playgroud)

表格

DO
LANGUAGE plpgsql
$$
DECLARE
  stmt text;
BEGIN
  FOR stmt IN
    WITH temp as (
    SELECT 'ALTER TABLE '|| schemaname || '."' || tablename ||'" OWNER TO newuser' as command
    FROM pg_tables WHERE NOT schemaname IN ('pg_catalog', 'information_schema')
    ORDER BY schemaname, tablename )
    SELECT command from temp
  LOOP
    EXECUTE stmt;
  END LOOP;
END;
$$;
Run Code Online (Sandbox Code Playgroud)

序列

DO
LANGUAGE plpgsql
$$
DECLARE
  stmt text;
BEGIN
  FOR stmt IN
    WITH temp as (
    SELECT 'ALTER SEQUENCE '|| sequence_schema || '."' || sequence_name ||'" OWNER TO newuser;' as command
    FROM information_schema.sequences WHERE NOT sequence_schema IN ('pg_catalog', 'information_schema')
    ORDER BY sequence_schema, sequence_name)
    select command from temp
  LOOP
    EXECUTE stmt;
  END LOOP;
END;
$$;
Run Code Online (Sandbox Code Playgroud)

意见

DO
LANGUAGE plpgsql
$$
DECLARE
  stmt text;
BEGIN
  FOR stmt IN
    WITH temp as (
    SELECT 'ALTER VIEW '|| table_schema || '."' || table_name ||'" OWNER TO newuser;' as command
    FROM information_schema.views WHERE NOT table_schema IN ('pg_catalog', 'information_schema')
    ORDER BY table_schema, table_name)
    select command from temp
  LOOP
    EXECUTE stmt;
  END LOOP;
END;
$$;
Run Code Online (Sandbox Code Playgroud)

模式

DO
LANGUAGE plpgsql
$$
DECLARE
  stmt text;
BEGIN
  FOR stmt IN
    WITH schema_names as(
    SELECT distinct(schemaname) FROM pg_tables WHERE NOT schemaname IN ('pg_catalog', 'information_schema')
    ORDER BY schemaname)
    SELECT 'ALTER SCHEMA '|| schemaname ||' OWNER TO newuser;' as command
    FROM schema_names
  LOOP
    EXECUTE stmt;
  END LOOP;
END;
$$;
Run Code Online (Sandbox Code Playgroud)

另请注意可能需要更改成员资格的数据库功能和其他组件

功能和触发功能

    DO
    LANGUAGE plpgsql
    $$
    DECLARE
      stmt text;
    BEGIN
      FOR stmt IN
        WITH temp as(
        SELECT 'alter function '||nsp.nspname||'.'||p.proname||'('||pg_get_function_identity_arguments(p.oid)||') owner to newuser;' as command
        FROM pg_proc p
        JOIN pg_namespace nsp ON p.pronamespace = nsp.oid
        WHERE NOT  nsp.nspname IN ('pg_catalog', 'information_schema'))
        SELECT command FROM temp
      LOOP
        EXECUTE stmt;
      END LOOP;
    END;
    $$;
Run Code Online (Sandbox Code Playgroud)

  • 谢谢!这是真正的现成可用的代码 (2认同)

mag*_*air 20

我最近不得不更改数据库中所有对象的所有权.虽然表,视图,触发器和序列有些容易更改,但上述方法对于函数失败,因为签名是函数名称的一部分.当然,我有一个MySQL背景,并不熟悉Postgres.

但是,pg_dump允许您只转储模式,这包含ALTER xxx所有者yyy; 你需要的陈述.这是关于这个话题的shell魔术

pg_dump -s YOUR_DB | grep -i 'owner to' | sed -e 's/OWNER TO .*;/OWNER TO NEW_OWNER;/i' | psqL YOUR_DB
Run Code Online (Sandbox Code Playgroud)


小智 19

非常简单

  1. su - postgres
  2. PSQL
  3. [old_user]对[new_user]进行重新分配;
  4. \ c [您的数据库]
  5. [old_user]对[new_user]进行重新分配;

完成.

  • 这_可能_做询问者想要的。到目前为止最简单。 (3认同)
  • 你参加聚会只晚了 4 年;向上滚动:/sf/answers/947462911/ (3认同)

小智 17

很简单,试试吧......

 select 'ALTER TABLE ' || table_name || ' OWNER TO myuser;' from information_schema.tables where table_schema = 'public';
Run Code Online (Sandbox Code Playgroud)

  • 您可以添加一条注释,指出必须复制和执行相应的字符串.不是说不明显:p (4认同)
  • 在命令末尾添加 `\gexec` 对我有用 `select 'ALTER TABLE ' || 表名 || ' myuser 的所有者;' 来自 information_schema.tables 其中 table_schema = 'public' \gexec` (3认同)

ely*_*sch 16

我喜欢这个,因为它修改,视图,序列功能有一定的所有者架构一个去(在一个SQL语句),而无需创建一个功能,你可以直接使用它的pgAdmin IIIPSQL:

(在PostgreSql v9.2中测试过)

DO $$DECLARE r record;
DECLARE
    v_schema varchar := 'public';
    v_new_owner varchar := '<NEW_OWNER>';
BEGIN
    FOR r IN 
        select 'ALTER TABLE "' || table_schema || '"."' || table_name || '" OWNER TO ' || v_new_owner || ';' as a from information_schema.tables where table_schema = v_schema
        union all
        select 'ALTER TABLE "' || sequence_schema || '"."' || sequence_name || '" OWNER TO ' || v_new_owner || ';' as a from information_schema.sequences where sequence_schema = v_schema
        union all
        select 'ALTER TABLE "' || table_schema || '"."' || table_name || '" OWNER TO ' || v_new_owner || ';' as a from information_schema.views where table_schema = v_schema
        union all
        select 'ALTER FUNCTION "'||nsp.nspname||'"."'||p.proname||'"('||pg_get_function_identity_arguments(p.oid)||') OWNER TO ' || v_new_owner || ';' as a from pg_proc p join pg_namespace nsp ON p.pronamespace = nsp.oid where nsp.nspname = v_schema
    LOOP
        EXECUTE r.a;
    END LOOP;
END$$;
Run Code Online (Sandbox Code Playgroud)

基于@rkj,@ AlannaRose,@ ShachonThomas,@ user3560574提供的答案以及@a_horse_with_no_name的答案

非常感谢.


更好的是:还要更改数据库模式所有者.

DO $$DECLARE r record;
DECLARE
    v_schema varchar := 'public';
    v_new_owner varchar := 'admin_ctes';
BEGIN
    FOR r IN 
        select 'ALTER TABLE "' || table_schema || '"."' || table_name || '" OWNER TO ' || v_new_owner || ';' as a from information_schema.tables where table_schema = v_schema
        union all
        select 'ALTER TABLE "' || sequence_schema || '"."' || sequence_name || '" OWNER TO ' || v_new_owner || ';' as a from information_schema.sequences where sequence_schema = v_schema
        union all
        select 'ALTER TABLE "' || table_schema || '"."' || table_name || '" OWNER TO ' || v_new_owner || ';' as a from information_schema.views where table_schema = v_schema
        union all
        select 'ALTER FUNCTION "'||nsp.nspname||'"."'||p.proname||'"('||pg_get_function_identity_arguments(p.oid)||') OWNER TO ' || v_new_owner || ';' as a from pg_proc p join pg_namespace nsp ON p.pronamespace = nsp.oid where nsp.nspname = v_schema
        union all
        select 'ALTER SCHEMA "' || v_schema || '" OWNER TO ' || v_new_owner 
        union all
        select 'ALTER DATABASE "' || current_database() || '" OWNER TO ' || v_new_owner 
    LOOP
        EXECUTE r.a;
    END LOOP;
END$$;
Run Code Online (Sandbox Code Playgroud)

  • 惊人的!为什么postgres不添加这个我不知道! (2认同)

小智 9

您可以在PostgreSQL 9中尝试以下操作

DO $$DECLARE r record;
BEGIN
    FOR r IN SELECT tablename FROM pg_tables WHERE schemaname = 'public'
    LOOP
        EXECUTE 'alter table '|| r.tablename ||' owner to newowner;';
    END LOOP;
END$$;
Run Code Online (Sandbox Code Playgroud)


小智 6

PostgreSQL中没有这样的命令.但你可以使用我前面描述的GRANTs 方法解决它.


Jud*_*dge 6

我不得不更改表,视图和序列的所有权,发现@rjk发布的出色解决方案可以正常工作-尽管有一个细节:如果对象名称是大小写混合的(例如“ TableName”),则将失败并显示“未找到”-错误。
为了避免这种情况,请使用“”将对象名称包装起来,如下所示:

桌子

SELECT 'ALTER TABLE \"'|| schemaname || '.' || tablename ||'\" OWNER TO my_new_owner;'
FROM pg_tables WHERE NOT schemaname IN ('pg_catalog', 'information_schema')
ORDER BY schemaname, tablename;
Run Code Online (Sandbox Code Playgroud)

顺序

SELECT 'ALTER SEQUENCE \"'|| sequence_schema || '.' || sequence_name ||'\" OWNER TO my_new_owner;'
FROM information_schema.sequences WHERE NOT sequence_schema IN ('pg_catalog', 'information_schema')
ORDER BY sequence_schema, sequence_name;
Run Code Online (Sandbox Code Playgroud)

观看次数

SELECT 'ALTER VIEW \"'|| table_schema || '.' || table_name ||'\" OWNER TO my_new_owner;'
FROM information_schema.views WHERE NOT table_schema IN ('pg_catalog', 'information_schema')
ORDER BY table_schema, table_name;
Run Code Online (Sandbox Code Playgroud)