PostgreSQLですべてのテーブルのOWNERを同時に変更する


411

PostgreSQLデータベースのすべてのテーブルの所有者を変更するにはどうすればよいですか?

試しましたALTER TABLE * OWNER TO new_ownerが、アスタリスク構文はサポートしていません。

回答:


460

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つすべてで同じであるため、おそらく少し乾燥させることができます。



10
+1アレックスに感謝します。私はあなたの答えに基づいて小さなbashスクリプトを作成しました。これはgist.github.com/2482969
gingerlime

10
@trygvisによる最近の回答を参照してください。はるかに簡単な答え:REASSIGN OWNED BY old_role [, ...] TO new_role
David

64
REASSIGN OWNED BYは、postgresが所有するオブジェクトに対しては機能しません。
BrunoJCM 2013

19
また、実際にREASSIGN OWNEDは、古いロールが所有するすべてのデータベースの所有権に影響します(postgresql.org/docs/9.3/static/sql-reassign-owned.htmlを参照)。したがって、1つのデータベースの所有権のみを変更する場合は、注意してください。
kitsune 2014年

3
@gingerlimeスクリプトに基づいて、bspkrs(彼の名前を見つけることができませんでした)は、関数も変更するスクリプトを作成しました:https
//gist.github.com/bspkrs/b997ed7f1eb1268f3403

538

REASSIGN OWNEDコマンドを使用できます。

あらすじ:

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

これにより、が所有するすべてのオブジェクトがold_role新しいロールに変更されます。ユーザーが持っているオブジェクトの種類について考える必要はありません。それらはすべて変更されます。これは単一のデータベース内のオブジェクトにのみ適用されることに注意してください。データベース自体の所有者も変更しません。

少なくとも8.2まで使用できます。彼らのオンラインドキュメントは、それよりもずっと前に遡ります。


ERROR: unexpected classid 3079。拡張機能がある場合、現在は機能しないと思います。
Steve Jorgensen 2013

40
作成したデータベース(システムデータベースではない)に接続しているにもかかわらず、これはユーザーpostgresでは機能しないようですが、次のように表示されます。システム
2013年

13
@thneeが報告したように、REASSIGNはデータベース内のすべてのオブジェクトに影響し、ユーザー定義オブジェクトとシステムオブジェクトを区別しないため、独自のテーブルを持つ拡張がある場合、postgresに対して機能しません。それでも私にはあまり役立たなかった(私のデータベースは以前はpostgresが所有していた)にもかかわらず、私は優雅さのためにこのオプションを(+1)好みます。
Pavel V.

6
明確にするために、このコマンドは現在接続しているデータベースでのみ機能します。old_roleが複数のデータベース内のオブジェクトを所有している場合、これらのデータベースのそれぞれでこのコマンドを接続して実行する必要があります
mavroprovato

11
これは、AWS RDS経由でホストされているpostgresでは機能しないようです。「オブジェクトを再割り当てするためのアクセス許可が拒否されました」というエラーが発生し、このリンクはその理由を示唆しています。 RDSで。」postgresql-archive.org/...
typoerrpr

197

これ: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 *.*

素晴らしいソリューション。私の唯一の問題は、スクリプトをエクスポートしてから、エクスポートしたスクリプトを実行したことです。私はSQL Serverの達人ですが、ショートカットを実行する方法がわかりません。[クエリを実行]をクリックしてpgScriptを実行しました。何が悪かったのですか?
Tyrone Moodley 2015

1
ログインするとplsql内から機能するため、私はこれを選択しました。UNIXレベルのスクリプト(現在のお気に入りの回答)では、環境に「-U postgres」とパスワードのエントリが必要です。
Dazed、2015

2
(1)psqlまたはpgAdminで実行できるため(2)変更するオブジェクトを簡単に確認できるため、私はこの回答を好みます。また、同様の機能ですが、stackoverflow.com / questions / 22803096 / …も使用しました。
AlannaRose 2015年

素晴らしいロジック。
Emipro Technologies Pvt。株式会社

42

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これを手伝ってください。


2
これは、関数、インデックス、シーケンスなどを含むスキーマ全体の所有権を変更するため、はるかに便利です。ありがとうございます。
liviucmg 2011年

スキーマの所有者は変更されません。スキーマの所有者を変更する方法も?
Andrus

@Andrus ALTER DATABASE $ DB OWNER TO $ OWNER;
ヨハンダーリン

データベースを変更すると、データベース所有者全体が変更されます。スキーマの所有者を変更する方法を尋ねました。
Andrusは、

ALTER SCHEMA fred OWNER TO betty;
Eric Aldinger

21

最近、データベース内のすべてのオブジェクトの所有権を変更する必要がありました。テーブル、ビュー、トリガー、シーケンスは多少簡単に変更されましたが、シグネチャは関数名の一部であるため、上記のアプローチは関数に対して失敗しました。確かに、私には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初めて使用しますが、特に大文字と小文字を区別しない一致を指定しているので、私の理解からは、これで十分です。
Bobort

19

とても簡単です、試してみてください...

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

4
対応する文字列をコピーして実行する必要があることに注意してください。はっきりしないわけではありません:p
夜景

これには、alterステートメント周辺のすべての引用符の削除が含まれます。この場合、マルチカーソルまたは置換が役立ちます。
Knowasilya 2014年

19

とてもシンプルです

  1. su-postgres
  2. psql
  3. [old_user]から[new_user]に割り当てられた再割り当て;
  4. \ c [データベース]
  5. [old_user]から[new_user]に割り当てられた再割り当て;

完了しました。


1
これはおそらく、求婚者が望んでいたことを行います。はるかに簡単です。
Geof Sawaya 2017

1
あなたはパーティーに4年遅れました。上にスクロール:stackoverflow.com/a/13535184/1772379
Ben Johnson

16

それが修飾するので、このような私のテーブルビューシーケンスおよび機能の特定の所有者のスキーマを一度の関数を作成し、あなたがそれを直接使用することができずに、(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$$;

すごい!なぜpostgresがこれを追加しないのか分かりません!
ピップ

2つの質問:1)最初と3番目の「ALTER TABLE」行はだまされているようです。これは意図的なものですか(所有権を変更するためにテーブルを2回パスする必要がありますか?)。2)シーケンスをリストしinformation_schema.sequencesているにもかかわらず、空であることがSELECT c.* FROM pg_class c WHERE c.relkind = 'S';わかります。なぜ一致しないのでしょうか?
GuyPaddock 2017

また、2番目のALTERクエリはALTER SEQUENCE
GuyPaddock 2017

12

テーブル、ビュー、シーケンスの所有権を変更する必要があり、@ 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;

10

あなたは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$$;

6

PostgreSQLにはそのようなコマンドはありません。しかし、GRANT について前に説明した方法を使用して回避できます。


とても素敵な記事ありがとうございます。今後の参考にさせていただきます。pgAdminを使用して、DBをバックアップし、DBを削除/削除し、new_ownerに必要な権限を一時的に付与し、復元ウィンドウで「所有者なし」オプションをオンにして、DBをnew_ownerとして再作成および復元しました。これにより、すべての所有者としてnew_ownerを使用して探していた結果が得られました。
カイ、

Postgres 9.3はREASSIGN OWNEDコマンドを導入しました。 postgresql.org/docs/9.3/sql-reassign-owned.html
Georg Zimmer

3

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 Sotoによる答えは正しいものであり、@ Yoav Anerによってアップロードされた要点も機能します(postgresで合法である)テーブル/ビュー名に特殊文字がない場合。

あなたはそれらをエスケープする必要があります、そして私はそのための要点をアップロードしました:https//gist.github.com/2911117


2
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のバージョン間を移行するための良いアプローチになる可能性があることも読んだことがあります。


2

そのための便利なスクリプトを作成しました。pg_change_db_owner.sh。このスクリプトは、データベーススキーマ内のすべてのテーブル、ビュー、シーケンス、関数の所有権を変更し、スキーマ自体の所有者も変更します。

特定のデータベースロールで所有されている特定のデータベース内のすべてのオブジェクトの所有権を変更するだけの場合は、REASSIGN OWNED代わりにコマンドを使用できます。


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のドキュメントでGRANTREVOKEこれに関する詳細をご覧ください。状況によっては、システムカタログ(pg_catalog.pg_*)に関連するトリックを使用する必要がある場合もありますが、それほど一般的ではありません。私は頻繁に次のことをしています。

  1. BEGIN プライバシーを変更するトランザクション
  2. の所有権を変更 DATABASES「DBAロール」に変更します
  3. の所有権をSCHEMAS「DBAロール」に変更します
  4. REVOKE ALLすべてのPRIVS TABLESSEQUENCESおよびFUNCTIONSすべてのロールから
  5. GRANT SELECT, INSERT, UPDATE, DELETE 適切なロールに関連する/適切なテーブル
  6. COMMIT DCLトランザクション。

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

次の簡単なシェルスクリプトは私にとってはうまくいきました。

#!/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

0

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.