Agent Skills by ALSEL
汎用DevOps・インフラ⭐ リポ 5品質スコア 67/100

Database Migration Script Generator

Liquibase、Flyway、Alembicのデータベースマイグレーションスクリプトを生成します。ロールバック安全性、データ保全、ゼロダウンタイムパターンに対応しています。マイグレーション実行時にシステムの停止を避けながら、安全にスキーマを変更できます。問題発生時のロールバック機能により、以前の状態へ確実に戻すことが可能です。既存データの損失を防ぎながら、本番環境での信頼性の高いデータベース更新を実現します。

description の原文を見る

Generate database migration scripts for Liquibase, Flyway, Alembic with rollback safety, data preservation, and zero-downtime patterns

SKILL.md 本文

目的と使用時期

トリガー条件:

  • アプリケーション更新に伴うデータベーススキーマの進化
  • ビジネスロジック変換を伴うデータマイグレーションの実行
  • スキーマ変更を必要とするゼロダウンタイム展開の実装
  • チーム全体のマイグレーションワークフローの標準化
  • データベースバージョンまたはプラットフォーム間のマイグレーション
  • 既存テーブルへのインデックス、制約、またはパーティショニングの追加

非対応:

  • 初期データベーススキーマの作成 (ORMモデルまたはDDLスクリプトを使用)
  • 単発のデータ修正 (トランザクション安全性を持つ直接SQLを使用)
  • データベースバックアップまたは復旧操作
  • データベース間のデータレプリケーション (ETLツールを使用)

事前チェック

時刻の正規化:

  • NIST/time.govセマンティクスを使用してNOW_ETを計算 (America/New_York、ISO-8601)
  • すべての引用アクセス日にNOW_ETを使用

入力検証:

  • migration_toolは以下のいずれかである必要があります: liquibase、flyway、alembic
  • databaseは以下のいずれかである必要があります: postgresql、mysql、sqlserver、oracle
  • migration_typeは以下のいずれかである必要があります: schema、data、hybrid
  • downtime_allowedは真偽値 (true/false) である必要があります
  • migration_descriptionは空でなく、説明的である必要があります

ソースの鮮度:


手順

T1: 基本的なスキーママイグレーション (≤2kトークン)

シンプルなDDL変更向けの高速パス:

  1. スキーマ変更の特定

    • カラムの追加/削除 (テーブルの再書き込みを避けるためのデフォルト値を含む)
    • テーブルの作成/削除
    • シンプルインデックスの追加/削除 (ユニークではない、単一カラム)
    • NOT NULL制約の追加/削除 (検証を含む)
  2. ツール固有のマイグレーション形式

    Liquibase (XML/YAML) アクセス日時: 2025-10-26T03:51:54-04:00

    <changeSet id="add-email-column" author="migration-generator">
      <addColumn tableName="users">
        <column name="email" type="VARCHAR(255)"/>
      </addColumn>
      <rollback>
        <dropColumn tableName="users" columnName="email"/>
      </rollback>
    </changeSet>
    

    Flyway (SQL) アクセス日時: 2025-10-26T03:51:54-04:00

    -- V1__add_email_column.sql
    ALTER TABLE users ADD COLUMN email VARCHAR(255);
    

    Alembic (Python) アクセス日時: 2025-10-26T03:51:54-04:00

    def upgrade():
        op.add_column('users', sa.Column('email', sa.String(255)))
    
    def downgrade():
        op.drop_column('users', 'email')
    
  3. 基本的なロールバックスクリプト

    • 各フォワード変更に対して逆操作を生成
    • ロールバック検証コメントを追加
    • 自動ロールバックが安全でない場合は手動ロールバック手順を含む

判定: データを伴わないシンプルなスキーマ変更の場合 → T1で終了。それ以外は T2 に進む。


T2: ロールバック機能付きデータマイグレーション (≤6kトークン)

データ変換を伴う拡張マイグレーション:

  1. データマイグレーションパターン アクセス日時: 2025-10-26T03:51:54-04:00

    既存データのバックフィル

    # Alembic: 新規カラムのデフォルト値をバックフィル
    def upgrade():
        op.add_column('users', sa.Column('status', sa.String(20), nullable=True))
        # 既存行をバックフィル
        op.execute("UPDATE users SET status = 'active' WHERE status IS NULL")
        # バックフィル後にNOT NULLにする
        op.alter_column('users', 'status', nullable=False)
    

    データ変換

    # Alembic: full_nameをfirst_nameとlast_nameに分割
    def upgrade():
        op.add_column('users', sa.Column('first_name', sa.String(100)))
        op.add_column('users', sa.Column('last_name', sa.String(100)))
        # データを変換
        connection = op.get_bind()
        users = connection.execute("SELECT id, full_name FROM users").fetchall()
        for user_id, full_name in users:
            parts = full_name.split(' ', 1)
            first = parts[0]
            last = parts[1] if len(parts) > 1 else ''
            connection.execute(
                "UPDATE users SET first_name = %s, last_name = %s WHERE id = %s",
                (first, last, user_id)
            )
        op.drop_column('users', 'full_name')
    
  2. ロールバック安全性パターン

    • べき等性: マイグレーションを複数回安全に実行できることを確認
    • チェックポイント: 破壊的操作前に検証クエリを追加
    • バックアップトリガー: データマイグレーション用の一時バックアップテーブルを作成
    • ドライランモード: 変更をプレビューするためのコメント付きSELECT文を含む
  3. 検証テスト アクセス日時: 2025-10-26T03:51:54-04:00

    -- マイグレーション後の検証
    SELECT COUNT(*) FROM users WHERE email IS NULL; -- 0であるべき
    SELECT COUNT(*) FROM users WHERE status NOT IN ('active', 'inactive'); -- 0であるべき
    
  4. データベース固有の考慮事項

    PostgreSQL アクセス日時: 2025-10-26T03:51:54-04:00

    • ALTER TABLE ... SET NOT NULLCHECK制約で先に使用
    • インデックス作成にはCONCURRENTLYを優先 (ゼロダウンタイム)
    • pg_stat_progress_create_indexを使用して長時間の操作を監視

    MySQL アクセス日時: 2025-10-26T03:51:54-04:00

    • オンラインDDLサポートの確認: ALGORITHM=INPLACE, LOCK=NONE
    • テーブルコピーが必要なALTER TABLEを回避 (8.0以前)
    • 大規模テーブルにはpt-online-schema-changeを使用 (Perconaツールキット)

    SQL Server

    • インデックス操作にWITH (ONLINE = ON)を使用
    • SSMS実行計画分析を活用
    • 大規模データマイグレーション用にSCHEMA_ONLYコピーを検討

T3: ゼロダウンタイムパターン (≤12kトークン)

本番システム向けの高度なパターン:

  1. 拡張/縮小パターン アクセス日時: 2025-10-26T03:51:54-04:00

    フェーズ1: 拡張 (新規スキーマを追加)

    # マイグレーション001: 新規カラムを追加、古いカラムは維持
    def upgrade():
        op.add_column('users', sa.Column('email_new', sa.String(255)))
        # 移行中に古い→新規をシンク化するトリガー
        op.execute("""
            CREATE TRIGGER sync_email_new
            BEFORE UPDATE ON users
            FOR EACH ROW
            BEGIN
                SET NEW.email_new = NEW.email;
            END;
        """)
    

    フェーズ2: データ移行

    # マイグレーション002: 新規カラムをバックフィル
    def upgrade():
        op.execute("UPDATE users SET email_new = email WHERE email_new IS NULL")
    

    フェーズ3: 縮小 (古いスキーマを削除)

    # マイグレーション003: 古いカラムを削除 (アプリケーション更新後)
    def upgrade():
        op.execute("DROP TRIGGER IF EXISTS sync_email_new")
        op.drop_column('users', 'email')
        op.alter_column('users', 'email_new', new_column_name='email')
    
  2. オンラインインデックス作成 アクセス日時: 2025-10-26T03:51:54-04:00

    PostgreSQL CONCURRENTLY

    -- Flyway: V5__add_email_index.sql
    CREATE INDEX CONCURRENTLY idx_users_email ON users(email);
    
    -- 検証
    SELECT schemaname, tablename, indexname, indexdef
    FROM pg_indexes
    WHERE indexname = 'idx_users_email';
    

    MySQL オンラインDDL

    -- Flyway: V6__add_composite_index.sql
    ALTER TABLE users
    ADD INDEX idx_email_status (email, status)
    ALGORITHM=INPLACE, LOCK=NONE;
    
  3. シャドウテーブルパターン (複雑な変換向け)

    # マイグレーション010: 新規スキーマでシャドウテーブルを作成
    def upgrade():
        op.create_table(
            'users_new',
            sa.Column('id', sa.Integer, primary_key=True),
            sa.Column('email', sa.String(255), nullable=False, index=True),
            sa.Column('status', sa.String(20), nullable=False)
        )
        # 古い→新規テーブルにデータをストリーム
        op.execute("""
            INSERT INTO users_new (id, email, status)
            SELECT id, email, COALESCE(status, 'active')
            FROM users
        """)
        # アトミックな名前変更 (ダウンタイム: ミリ秒)
        op.rename_table('users', 'users_old')
        op.rename_table('users_new', 'users')
    
  4. 展開ガイドテンプレート

    ## 展開手順
    
    ### マイグレーション前
    1. データベースバックアップが完了したことを確認 (過去24時間)
    2. アプリケーション接続プール設定を確認 (タイムアウト ≥ 30秒)
    3. クエリパフォーマンスベースラインを確認 (pg_stat_statements)
    
    ### マイグレーション実行
    1. トランザクション内でマイグレーションを実行 (サポートされている場合)
    2. ロック待ちを監視: `SELECT * FROM pg_locks WHERE NOT granted`
    3. 行数を検証: `SELECT COUNT(*) FROM users`
    
    ### マイグレーション後
    1. ANALYZEを実行して統計情報を更新
    2. アプリケーションログを確認 (制約違反がないか)
    3. クエリパフォーマンスを監視 (ベースラインと比較)
    
    ### ロールバック手順 (必要な場合)
    1. アプリケーショントラフィックを停止 (またはフィーチャーフラグを使用)
    2. ロールバックスクリプトを実行: `flyway undo`または`alembic downgrade -1`
    3. データ整合性を検証: `SELECT * FROM users LIMIT 10`
    4. ロールバックが失敗した場合はバックアップから復旧
    
  5. ブルーグリーンデータベースマイグレーション アクセス日時: 2025-10-26T03:51:54-04:00

    • データベースインスタンスを複製 (Blue = 古いスキーマ、Green = 新規スキーマ)
    • Greenインスタンスでマイグレーションを実行
    • 移行中のデュアルライトパターン (アプリケーションが両方に書き込み)
    • カットオーバー: 接続文字列をGreenに更新
    • 検証期間: Blue をオンラインに保持 (24~48時間)

判定ルール

マイグレーションツールの選択:

  • Liquibase: マルチデータベースサポート、XML/YAML宣言的変更、複雑なロールバックに最適
  • Flyway: SQL優先のチーム、シンプルなバージョニング、Java/Springエコシステムに最適
  • Alembic: SQLAlchemyを使用するPythonアプリケーション、プログラマティックなマイグレーションに最適

ダウンタイム許容度によるマイグレーション戦略:

  • downtime_allowed = true: 直接ALTER TABLEを使用、高速実行、シンプルなスクリプト
  • downtime_allowed = false: 拡張/縮小、CONCURRENTLY、シャドウテーブルを使用、より長いタイムライン

データベース固有パターン:

  • PostgreSQL: インデックスはCONCURRENTLYを優先、NOT NULLの前にCHECK制約を使用
  • MySQL: ALGORITHM=INPLACEサポートを検証、InnoDBにはpt-online-schema-changeを使用
  • SQL Server: ONLINE=ONを使用、分析ワークロードにはcolumnstoreインデックスを検討
  • Oracle: Oracle Data Redefinition (DBMS_REDEFINITION) をゼロダウンタイムに使用

中止条件:

  • 無効なツール/データベース組み合わせ → エラー「Tool X does not support database Y」
  • ロールバック不可の破壊的操作 → エラー「Cannot generate safe rollback for DROP TABLE」
  • ゼロダウンタイムを要求したが非対応操作 → エラー「Zero-downtime not possible for operation X」

データ保全性チェック:

  • カラムの削除: カラムに非NULL データが含まれる場合は警告
  • 型の変更: データが新規型に適合することを検証 (VARCHAR(50) → VARCHAR(20))
  • NOT NULLの追加: デフォルト値またはバックフィル戦略を要求

出力契約

スキーマ (JSON):

{
  "migration_tool": "liquibase | flyway | alembic",
  "database": "postgresql | mysql | sqlserver | oracle",
  "migration_type": "schema | data | hybrid",
  "downtime_allowed": "真偽値",
  "migration_script": {
    "filename": "文字列 (例: V5__add_email_column.sql)",
    "content": "文字列 (ツール固有のマイグレーションコード)"
  },
  "rollback_script": {
    "filename": "文字列 (例: U5__undo_email_column.sql)",
    "content": "文字列 (逆向きマイグレーションコード)",
    "manual_steps": ["文字列 (自動ロールバックが安全でない場合)"]
  },
  "validation_tests": [
    {
      "description": "文字列",
      "query": "文字列 (SQL検証クエリ)",
      "expected_result": "文字列"
    }
  ],
  "deployment_guide": {
    "pre_migration_steps": ["文字列"],
    "execution_steps": ["文字列"],
    "post_migration_steps": ["文字列"],
    "rollback_procedure": ["文字列"],
    "estimated_duration": "文字列 (例: '5 minutes'、'2 hours')"
  },
  "warnings": ["文字列 (潜在的な問題または破壊的な変更)"],
  "timestamp": "ISO-8601文字列 (NOW_ET)"
}

必須フィールド:

  • migration_tooldatabasemigration_typedowntime_allowedmigration_scriptrollback_scriptvalidation_testsdeployment_guidetimestamp

安全性保証:

  • すべてのDDL変更には明示的なロールバックが必要 (または手動ロールバック手順)
  • データマイグレーションには行数検証を含める必須
  • ゼロダウンタイムマイグレーションはロック期間の推定を指定する必須

例1: シンプルなカラム追加 (Alembic + PostgreSQL)

"""users テーブルにメールカラムを追加し、NOT NULL制約を適用

Revision ID: a1b2c3d4e5f6
Revises: previous_revision
Create Date: 2025-10-26 03:51:54.000000

"""
from alembic import op
import sqlalchemy as sa

def upgrade():
    # 最初はnullableでカラムを追加
    op.add_column('users', sa.Column('email', sa.String(255), nullable=True))

    # プレースホルダーでバックフィル (アプリケーションが更新)
    op.execute("UPDATE users SET email = CONCAT('user', id, '@example.com') WHERE email IS NULL")

    # NOT NULL制約を追加
    op.alter_column('users', 'email', nullable=False)

    # パフォーマンス向けにインデックスを追加
    op.create_index('idx_users_email', 'users', ['email'], unique=True)

def downgrade():
    op.drop_index('idx_users_email', table_name='users')
    op.drop_column('users', 'email')

品質ゲート

トークン予算:

  • T1: ≤2kトークン (シンプルなスキーマ変更、基本的なロールバック)
  • T2: ≤6kトークン (データマイグレーション、検証テスト、データベース固有の最適化)
  • T3: ≤12kトークン (ゼロダウンタイムパターン、展開ガイド、マルチフェーズマイグレーション)

安全性:

  • マイグレーションスクリプトにプレーンテキストの認証情報がない (環境変数を使用)
  • すべての破壊的操作には明示的な確認コメントが必要
  • ロールバックスクリプトがサンプルデータに対してテスト済み

監査可能性:

  • マイグレーションID/バージョンはツール慣例に従う (Flyway: V1__description.sql、Alembic: revision ID)
  • すべてのマイグレーションに著者、タイムスタンプ、説明を含める
  • データベース固有の構文を公式ドキュメントに対して検証

決定論性:

  • 同じ入力 → 同一のマイグレーションスクリプト
  • べき等なマイグレーション (複数回安全に実行可能)
  • 予測可能なロールバック動作

パフォーマンス:

  • DDL操作のロック期間を推定
  • 10k行以上を影響するデータマイグレーションにはEXPLAIN ANALYZEを含める
  • 大規模テーブル変換のバッチサイズを推奨 (例: 1000行/バッチ)

リソース

公式ドキュメント (アクセス日時: 2025-10-26T03:51:54-04:00):

  1. Liquibase Change Types - DDL/DML操作
  2. Flyway SQL Migrations - バージョン管理されたマイグレーション
  3. Alembic Operations Reference - Pythonマイグレーション API
  4. PostgreSQL ALTER TABLE - DDL構文
  5. MySQL Online DDL - ゼロダウンタイム操作
  6. SQL Server Online Index Operations - オンラインDDL

マイグレーションパターン:

ベストプラクティス:

ツール比較:

ライセンス: Apache-2.0(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
williamzujkowski
リポジトリ
williamzujkowski/cognitive-toolworks
ライセンス
Apache-2.0
最終更新
2026/4/18

Source: https://github.com/williamzujkowski/cognitive-toolworks / ライセンス: Apache-2.0

本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: williamzujkowski · williamzujkowski/cognitive-toolworks · ライセンス: Apache-2.0