👌

Flyway + PostgreSQL 実践Tips集:複数プロジェクト対応 & 存在チェック付きマイグレーション

に公開

PostgreSQL x Flyway で "IF EXISTS" 的なチェックをしたい

Flywayを使ってPostgreSQLのスキーママイグレーションをする際に、「既にデータが存在している場合はスキップしたい」という地味だけど重要な必要性は高いです。


PostgreSQL で Flyway + IF EXISTS をつかう2つの方法

1. DO $$ BEGIN ... END $$; + SELECT FROM VALUES

DO $$
DECLARE
  rec RECORD;
BEGIN
  FOR rec IN
    SELECT * FROM (
      VALUES
        ('key1', 'holder1', 'item1', 'value1', NULL),
        ('key2', 'holder2', 'item2', 'value2', NULL)
    ) AS t(col_category, col_holder, col_item, col_value, col_note)
  LOOP
    INSERT INTO config_table (category, holder, settingitem, setvalue, memo)
    VALUES (rec.col_category, rec.col_holder, rec.col_item, rec.col_value, rec.col_note)
    ON CONFLICT (category, holder, settingitem)
    DO UPDATE SET setvalue = EXCLUDED.setvalue, memo = EXCLUDED.memo;
  END LOOP;
END $$;
  • 複合キー + 複数レコードの処理に最適
  • Flyway の .sql スクリプトとして完全に動作

2. ALTER や CREATE の存在チェック

テーブルやカラムの追加/削除も Flyway マイグレーションでよく使います。その際は IF NOT EXISTS / IF EXISTS を使いましょう。

CREATE TABLE IF NOT EXISTS
CREATE TABLE IF NOT EXISTS example_table (
  id SERIAL PRIMARY KEY,
  name TEXT
);
ALTER TABLE IF COLUMN NOT EXISTS(PostgreSQLには直接構文はないが、以下のように書く)
DO $$
BEGIN
  IF NOT EXISTS (
    SELECT 1 FROM information_schema.columns 
    WHERE table_name='example_table' AND column_name='new_column'
  ) THEN
    ALTER TABLE example_table ADD COLUMN new_column TEXT;
  END IF;
END $$;
DROP TABLE IF EXISTS
DROP TABLE IF EXISTS old_table;

【Tips】複数プロジェクトで Flyway を利用する際のポイント

flyway_schema_history はプロジェクトごとに分ける

  • Flyway は「マイグレーション履歴」を flyway_schema_history テーブルで管理
  • 複数プロジェクトで利用する場合:
    • DBスキーマは同じ
    • Flywayの "table" 設定でヒストリー名を変える
flyway -table=flyway_schema_history_projectA migrate
flyway -table=flyway_schema_history_projectB migrate

▶ SQL ファイルはサブフォルダで分ける

  • sql/projectA/ , sql/projectB/ などの構成に
  • flyway.locations=filesystem:sql/projectA とすれば分離で実行可能

▶ Flyway スクリプト内でことなき処理をしたいとき

  • マイグレーション失敗を防ぐため
  • 既存チェック: SELECT EXISTS(...)
  • プラグマ ブロックで DO $$ BEGIN ... END $$;

【おわりに】

PostgreSQL + Flyway の組み合わせは非常に強力ですが、少しの設計ミスでトラブルの元になります。

  • スキー重複を済ませるUPSERTパターン
  • DO $$ でのループ & ロジック切り出し
  • プロジェクトの分離管理

これらを駆使することで、本番もローカルも安心なデータライフが実現できます。

Accenture Japan (有志)

Discussion