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

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

我尝试了ALTER TABLE * OWNER TO new_owner但它不支持星号语法。

请参阅REASSIGN OWNED命令

注意:正如@trygvis 在下面的答案中提到的那样 , REASSIGN OWNED命令至less可以从版本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 

序列:

 for tbl in `psql -qAt -c "select sequence_name from information_schema.sequences where sequence_schema = 'public';" YOUR_DB` ; do psql -c "alter table \"$tbl\" owner to NEW_OWNER" YOUR_DB ; done 

浏览次数:

 for tbl in `psql -qAt -c "select table_name from information_schema.views where table_schema = 'public';" YOUR_DB` ; do psql -c "alter table \"$tbl\" owner to NEW_OWNER" YOUR_DB ; done 

你可能会干起来一点,因为所有三个alter语句是相同的。


您可以使用REASSIGN OWNED命令。

概要:

 REASSIGN OWNED BY old_role [, ...] TO new_role 

这将old_role拥有的所有对象更改为新的angular色。 你不必考虑用户拥有什么样的对象,他们都将被改变。 请注意,它只适用于单个数据库内的对象。 它不会改变数据库本身的所有者。

它可以回到至less8.2。 他们的在线文档只是在遥远的地方。

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

 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; 

序列

 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; 

查看

 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; 

物化视图

根据这个答案

 SELECT 'ALTER TABLE '|| oid::regclass::text ||' OWNER TO my_new_owner;' FROM pg_class WHERE relkind = 'm' ORDER BY oid; 

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

通过执行以下命令来检查你的psql工作:

 \dt *.* \ds *.* \dv *.* 

如果你想在一个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$; 

然后你可以执行这个查询,它将改变表,序列和视图的所有者:

 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; 

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

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

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

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

但是, pg_dump允许您只转储模式,并且这包含ALTER xxx OWNER TO yyy; 你需要的陈述。 这是我在这个话题上的一点魔力

 pg_dump -s YOUR_DB | grep -i 'owner to' | sed -e 's/OWNER TO .*;/OWNER TO NEW_OWNER;/i' | psqL YOUR_DB 

很简单,试试吧…

  select 'ALTER TABLE ' || table_name || ' OWNER TO myuser;' from information_schema.tables where table_schema = 'public'; 

很简单

  1. su – postgres
  2. PSQL
  3. 将[old_user]拥有的重新分配给[new_user];
  4. \ c [你的数据库]
  5. 将[old_user]拥有的重新分配给[new_user];

完成。

我喜欢这个,因为它一次性修改某个模式的 视图序列函数的所有者(在一个sql语句中),而不会创build一个函数,您可以直接在PgAdmin IIIpsql中使用它:

(在PostgreSql v9.2中testing)

 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 ra; END LOOP; END$$; 

基于@rkj,@AlannaRose,@SharoonThomas,@ 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 ra; END LOOP; END$$; 

你可以在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$$; 

PostgreSQL中没有这样的命令。 但是你可以使用我之前描述的GRANT的方法来解决这个问题。

基于elysch的答案 ,这是一个多模式的解决scheme:

 DO $$ DECLARE r record; i int; v_schema text[] := '{public,schema1,schema2,schema3}'; v_new_owner varchar := 'my_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 = ANY (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 = ANY (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 = ANY (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 = ANY (v_schema) union all select 'ALTER DATABASE "' || current_database() || '" OWNER TO ' || v_new_owner LOOP EXECUTE ra; END LOOP; FOR i IN array_lower(v_schema,1) .. array_upper(v_schema,1) LOOP EXECUTE 'ALTER SCHEMA "' || v_schema[i] || '" OWNER TO ' || v_new_owner ; END LOOP; END $$; 

@Alex Soto的答案是正确的,由@Yoav Aner上传的要点也提供了在表格/视图名称中没有特殊字符(这在postgres中是合法的)。

你需要逃避他们的工作,我已经上传的要点: https : //gist.github.com/2911117

从PostgreSQL 9.0开始,你有能力在GRANT [priv name] ON ALL [object type] IN SCHEMA中赋予GRANT [priv name] ON ALL [object type] IN SCHEMA ,其中[priv name]是典型的SELECT, INSERT, UPDATE, DELETE, etc[object type]可以是下列之一:

  • TABLES
  • SEQUENCES
  • FUNCTIONS

关于GRANTREVOKE PostgreSQL的文档更详细地介绍了这一点。 在某些情况下,仍然需要使用涉及系统目录的技巧( pg_catalog.pg_* ),但这种技巧并不常见。 我经常这样做:

  1. BEGIN一个交易来修改priv
  2. DATABASES所有权更改为“DBAangular色”
  3. SCHEMAS所有权更改为“DBAangular色”
  4. REVOKE ALL所有angular色的所有TABLESSEQUENCESFUNCTIONS REVOKE ALL权限
  5. 在相关/合适的表格上GRANT SELECT, INSERT, UPDATE, DELETE适当的angular色
  6. COMMIT DCL交易。
 pg_dump as insert statements pg_dump -d -O database filename -d ( data as inserts ) -O ( capital O is no owner ) 

然后使用以下命令将备份文件重新传回到PostgreSQL:

 psql -d database -U username -h hostname < filename 

由于没有包含所有者,那么所有创build的表,模式等都是在您指定的login用户下创build的。

我读过这可能是PostgreSQL版本之间迁移的好方法。

被接受的解决scheme不考虑function的所有权,下面的解决scheme处理所有事情(在审查时,我注意到它类似于上面的@magiconair)

 echo "Database: ${DB_NAME}" echo "Schema: ${SCHEMA}" echo "User: ${NEW_OWNER}" pg_dump -s -c -U postgres ${DB_NAME} | egrep "${SCHEMA}\..*OWNER TO"| sed -e "s/OWNER TO.*;$/OWNER TO ${NEW_OWNER};/" | psql -U postgres -d ${DB_NAME} # do following as last step to allow recovery psql -U postgres -d postgres -c "ALTER DATABASE ${DB_NAME} OWNER TO ${NEW_OWNER};" 

我为此创build了一个方便的脚本。 pg_change_db_owner.sh 。 此脚本更改数据库模式中所有表,视图,序列和函数的所有权,也更改模式本身的所有者。

请注意,如果您只想更改特定数据库中所有对象的所有权,那么您可以简单地使用命令REASSIGN OWNED

以下更简单的shell脚本为我工作。

 #!/bin/bash for i in `psql -U $1 -qt -c "select tablename from pg_tables where schemaname='$2'"` do psql -U $1 -c "alter table $2.$i set schema $3" done 

input$ 1 – 用户名(数据库)$ 2 =现有模式$ 3 =到新模式。

和@ AlexSoto的function一样:

 IFS=$'\n' for fnc in `psql -qAt -c "SELECT '\"' || p.proname||'\"' || '(' || pg_catalog.pg_get_function_identity_arguments(p.oid) || ')' FROM pg_catalog.pg_namespace n JOIN pg_catalog.pg_proc p ON p.pronamespace = n.oid WHERE n.nspname = 'public';" YOUR_DB` ; do psql -c "alter function $fnc owner to NEW_OWNER" YOUR_DB; done 

Docker:修改所有表+序列的所有者

 export user="your_new_owner" export dbname="your_db_name" cat <<EOF | docker run -i --rm --link postgres:postgres postgres sh -c "psql -h \$POSTGRES_PORT_5432_TCP_ADDR -p \$POSTGRES_PORT_5432_TCP_PORT -U postgres -d $dbname" | grep ALTER | docker run -i --rm --link postgres:postgres postgres sh -c "psql -h \$POSTGRES_PORT_5432_TCP_ADDR -p \$POSTGRES_PORT_5432_TCP_PORT -U postgres -d $dbname" SELECT 'ALTER TABLE '||schemaname||'.'||tablename||' OWNER TO $user;' FROM pg_tables WHERE schemaname = 'public'; SELECT 'ALTER SEQUENCE '||relname||' OWNER TO $user;' FROM pg_class WHERE relkind = 'S'; EOF