修改所拥有的所有PostgreSQL中REASSIGN同时表OWNER

问题描述 投票:372回答:20

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

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

postgresql
20个回答
433
投票

See REASSIGN OWNED command

注:由于@trygvis mentions in the answer belowREASSIGN 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

序列:

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

浏览次数:

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

你也许可以DRY说了一下,因为ALTER语句对所有三个相同。



7
投票

在PostgreSQL里没有这样的命令。但是你可以使用方法我described前段时间补助解决它。


5
投票

我不得不改变的表,视图和序列的所有权,发现张贴@rjk了很好的解决方案工作正常 - 尽管一个细节:如果对象名称是混合大小写(如“表名”),这将失败,并“没有找到“误差。 为了避免这个,换用'“的对象名称如下:

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;

3
投票

基于该answer by elysch,这里是多种模式的解决方案:

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 r.a;
    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
$$;

2
投票

通过@Alex索托的答案是正确的,并通过@Yoav安尔上传的主旨也创作,但在表/视图名称(这是在Postgres的法律)没有特殊字符。

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


1
投票

在PostgreSQL的9.0开始,你必须GRANT [priv name] ON ALL [object type] IN SCHEMA其中[priv name]是典型的SELECT, INSERT, UPDATE, DELETE, etc[object type]可以是一个能力:

  • TABLES
  • SEQUENCES
  • FUNCTIONS

PostgreSQL的上GRANT和文档REVOKE进去对此更详细。在某些情况下,它仍然需要使用涉及到系统目录(pg_catalog.pg_*)的技巧,但它并不像常见。我经常做到以下几点:

  1. BEGIN事务修改PRIVS
  2. 更改DATABASES的所有权转让给“DBA的角色”
  3. 更改SCHEMAS所有权有关的“DBA角色”
  4. 从所有角色都REVOKE ALLTABLESSEQUENCES FUNCTIONS PRIVS
  5. GRANT SELECT, INSERT, UPDATE, DELETE对相关/适当的表格,以适当的角色
  6. COMMIT的DCL交易。

1
投票
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

至于有那么包括了所有创建的表,模式等方面没有所有者,你指定的登录用户下创建的。

我已阅读,这可能是对PostgreSQL版本之间迁移,以及一个不错的办法。


1
投票

接受的解决方案不采取以下解决方案保健功能的所有权进行所有的(在审查我注意到,它类似于上面@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};"

1
投票

我创建了一个方便的脚本; pg_change_db_owner.sh。该脚本改变所有权的数据库架构中的所有表,视图,序列和功能,也所有者的模式本身。

请注意,如果你想只改变所有对象的所有权,在一个特定的数据库,通过一个特定的数据库角色所拥有,那么你可以简单地使用命令REASSIGN OWNED代替。


1
投票

下面简单的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

当输入$第1 - 用户名(数据库)$ 2 =现有架构$ 3 =新模式。


1
投票

同@ AlexSoto的做法进行功能:

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

510
投票

您可以使用REASSIGN OWNED命令。

概要:

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

这改变了由old_role资到新角色中的所有对象。你不必去想什么样的用户拥有的对象,他们都将被改变。请注意,它仅适用于对象的单一数据库中。它不会改变数据库本身的所有者要么。

它可以回到至少8.2。他们的在线文档只去那么远了。


0
投票

Docker: Modify Owner of all Tables + Sequences

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

177
投票

这: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;

序列

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;

物化视图

基于this answer

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 *.*

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$;

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

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的新名称。

在大多数情况下,你需要成为超级用户才能执行此。您可以通过改变从自己的用户店主你是成员的角色组避免这种情况。

由于RhodiumToad上#postgresql帮助了这一点。


20
投票

最近,我不得不改变所有对象的所有权在数据库中。虽然表,视图,触发器和序列稍微容易地改变上述方法失败用作签名是函数名的一部分。当然,我有一个MySQL的背景,我不那么熟悉的Postgres。

然而,pg_dump的允许你只转储模式,这包含了ALTER XXX所有者YYY;你需要声明。这是我的魔贝位的话题

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

18
投票

很简单

  1. 苏 - 的Postgres
  2. PSQL
  3. REASSIGN归[OLD_USER]至[new_user];
  4. \ C [数据库]
  5. REASSIGN归[OLD_USER]至[new_user];

完成。


16
投票

很简单,试试吧...

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

16
投票

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

(在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$$;

基于由@rkj,@AlannaRose,@SharoonThomas,@ user3560574和@a_horse_with_no_name this answer提供的答案

非常感谢。


更妙的是:也更改数据库和架构所有者。

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$$;

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$$;
© www.soinside.com 2019 - 2024. All rights reserved.