回答:
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
alterステートメントは3つすべてで同じであるため、おそらく少し乾燥させることができます。
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もまた素晴らしく高速なソリューションであり、1つのデータベースの複数のスキーマで機能します。
テーブル
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 *.*
1つのsqlステートメントで実行する場合は、http: //wiki.postgresql.org/wiki/Dynamic_DDLで説明されているように、exec()関数を定義する必要があります。
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これを手伝ってください。
最近、データベース内のすべてのオブジェクトの所有権を変更する必要がありました。テーブル、ビュー、トリガー、シーケンスは多少簡単に変更されましたが、シグネチャは関数名の一部であるため、上記のアプローチは関数に対して失敗しました。確かに、私には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';
とてもシンプルです
完了しました。
それが修飾するので、このような私のテーブル、ビュー、シーケンスおよび機能の特定の所有者のスキーマをに一度の関数を作成し、あなたがそれを直接使用することができずに、(1つの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によって投稿された優れたソリューションが正常に機能していることがわかりました。見つかりません」エラー。
これを回避するには、次のようにオブジェクト名を「」で囲みます。
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 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$$;
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
$$;
@Alex Sotoによる答えは正しいものであり、@ Yoav Anerによってアップロードされた要点も機能します(postgresで合法である)テーブル/ビュー名に特殊文字がない場合。
あなたはそれらをエスケープする必要があります、そして私はそのための要点をアップロードしました:https://gist.github.com/2911117
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のバージョン間を移行するための良いアプローチになる可能性があることも読んだことがあります。
そのための便利なスクリプトを作成しました。pg_change_db_owner.sh。このスクリプトは、データベーススキーマ内のすべてのテーブル、ビュー、シーケンス、関数の所有権を変更し、スキーマ自体の所有者も変更します。
特定のデータベースロールで所有されている特定のデータベース内のすべてのオブジェクトの所有権を変更するだけの場合は、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
すべてのPRIVS 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