Answers:
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
顺序:
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语句对所有三个相同。
REASSIGN OWNED BY old_role [, ...] TO new_role
您可以使用该REASSIGN OWNED
命令。
REASSIGN OWNED BY old_role [, ...] TO new_role
这会将所有拥有的对象更改old_role
为新角色。您不必考虑用户拥有哪种对象,它们都将被更改。请注意,它仅适用于单个数据库内的对象。它也不会更改数据库本身的所有者。
至少可以恢复到8.2。他们的在线文档可以追溯到很久以前。
ERROR: unexpected classid 3079
。我想如果有任何扩展名,当前是行不通的。
这是: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;
物化视图
根据这个答案
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新名称。
在大多数情况下,您需要成为超级用户才能执行此操作。通过将所有者从您自己的用户更改为您所属的角色组,可以避免这种情况。
感谢#postgresql上的RhodiumToad对此提供了帮助。
最近,我不得不更改数据库中所有对象的所有权。尽管表,视图,触发器和序列在某种程度上很容易更改,但是上述方法对于函数来说是失败的,因为签名是函数名称的一部分。当然,我有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
grep
命令。我本人是Linux的新手,但据我了解,这似乎sed
很好用,尤其是因为无论如何您都指定不区分大小写的匹配。
非常简单,尝试一下...
select 'ALTER TABLE ' || table_name || ' OWNER TO myuser;' from information_schema.tables where table_schema = 'public';
很简单
完成。
我这样的之一,因为它修改表,视图,序列和功能有一定的所有者架构在一个去(在一个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的答案
非常感谢。
更妙的是:还更改数据库和架构所有者。
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$$;
information_schema.sequences
即使SELECT c.* FROM pg_class c WHERE c.relkind = 'S';
列出序列也为空。为什么它们不匹配?
ALTER
查询不应该是ALTER SEQUENCE
吗?
我不得不更改表,视图和序列的所有权,发现@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;
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;
PostgreSQL中没有这样的命令。但是您可以使用我之前为GRANTs 描述的方法来解决它。
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
$$;
@Alex Soto的答案是正确的,并且@Yoav Aner上传的要旨也可以,只要表/视图名称中没有特殊字符(在postgres中是合法的)即可。
您需要让他们逃脱工作,我为此上传了要点:https : //gist.github.com/2911117
我为此创建了一个方便的脚本;pg_change_db_owner.sh。此脚本更改数据库模式中所有表,视图,序列和函数的所有权,以及模式本身的所有者。
请注意,如果您只想更改特定数据库角色拥有的特定数据库中所有对象的所有权,则可以简单地使用command REASSIGN OWNED
代替。
在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_*
)的技巧,但这并不普遍。我经常执行以下操作:
BEGIN
修改特权的交易DATABASES
为“ DBA角色”SCHEMAS
为“ DBA角色”REVOKE ALL
所有人TABLES
,SEQUENCES
以及FUNCTIONS
所有角色GRANT SELECT, INSERT, UPDATE, DELETE
在相关/适当的表上扮演适当的角色COMMIT
DCL交易。接受的解决方案不会处理功能所有权,而解决方案会处理所有内容(在查看时,我注意到它类似于上面的@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};"
与@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
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