PostgreSQL:すべてのスキーマでDDLを実行する


8

マルチテナントDBセットアップを行っており、いくつかの列を追加する必要があります。ユーザーをパーティション分割するためにスキーマ(およびsearch_path)を使用しているので、すべてのデータベースにDDLスキーマの変更を適用するユビキタスな方法を探しています。最初は、単一のクエリ(pg_catalogのカーソル)として実行できるかもしれないと思っていましたが、コマンドラインでの呼び出しがpsql -f望ましい方法かもしれません。


@RolandoMySQLDBA:Postgres代わりにPostgreSQL完全に問題ありません。
a_horse_with_no_name 2013年

回答:


11

私は後者の解決策を好みます。スキーマ名を次のファイル(1行に1つのスキーマ)に収集できますpsql

\o change_schema.sql
\t on

SELECT n.nspname
FROM pg_catalog.pg_namespace n
WHERE n.nspname !~ '^pg_' AND n.nspname <> 'information_schema';

-- reset the output
\o
\t off

次に、以下を簡単に実行できます。

change_schema.sql含めるスキーマを参照せずに、DDL変更スクリプト(など)を用意する

SET search_path TO :schema;

BEGIN;
...
...
ALTER TABLE orders
ADD COLUMN last_modified timestamp;
...
...
COMMIT;

次に、スキーマリストのすべての行を次のような行に変えることができます

psql -h dbhost -d targetdb -f change_schema.sql -v schema=<schema_name>

sedたとえば、単純なコマンドで-次に、これらのコマンドを実行する必要があります。もちろん、必要に応じて適切なシェルスクリプトに変換できます。


1
これは私が行う方法でもありますが、sedするのではなく、シェルを使用てスキーマリストをループ処理するので、エラー処理が向上しました。完全を期すために、もう1つのアプローチはEXECUTE、ステートメントを動的SQLとして実行するために使用されるPL / PgSQLプロシージャとして記述することです。
クレイグリンガー2013年

9

完全を期すために、別のアプローチは、すべてのスキーマをループし、PL / PgSQLで動的SQLを使用して変更を実行することです。例:

DO
$$
DECLARE
    schemaname name;
BEGIN
   FOR schemaname IN SELECT nspname FROM pg_namespace WHERE nspname NOT LIKE 'pg_%' AND nspname <> 'information_schema' LOOP
       EXECUTE format('ALTER TABLE %I.my_table ADD COLUMN blah blah;', schemaname);
   END LOOP;
END;
$$ LANGUAGE plpgsql;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.