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、alembicdatabaseは以下のいずれかである必要があります: postgresql、mysql、sqlserver、oraclemigration_typeは以下のいずれかである必要があります: schema、data、hybriddowntime_allowedは真偽値 (true/false) である必要がありますmigration_descriptionは空でなく、説明的である必要があります
ソースの鮮度:
- Liquibaseドキュメントがアクセス可能である アクセス日時: 2025-10-26T03:51:54-04:00
- Flywayドキュメントがアクセス可能である アクセス日時: 2025-10-26T03:51:54-04:00
- Alembicドキュメントがアクセス可能である アクセス日時: 2025-10-26T03:51:54-04:00
- PostgreSQLオンラインDDLドキュメントがアクセス可能である アクセス日時: 2025-10-26T03:51:54-04:00
- MySQLオンラインDDLドキュメントがアクセス可能である アクセス日時: 2025-10-26T03:51:54-04:00
手順
T1: 基本的なスキーママイグレーション (≤2kトークン)
シンプルなDDL変更向けの高速パス:
-
スキーマ変更の特定
- カラムの追加/削除 (テーブルの再書き込みを避けるためのデフォルト値を含む)
- テーブルの作成/削除
- シンプルインデックスの追加/削除 (ユニークではない、単一カラム)
- NOT NULL制約の追加/削除 (検証を含む)
-
ツール固有のマイグレーション形式
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') -
基本的なロールバックスクリプト
- 各フォワード変更に対して逆操作を生成
- ロールバック検証コメントを追加
- 自動ロールバックが安全でない場合は手動ロールバック手順を含む
判定: データを伴わないシンプルなスキーマ変更の場合 → T1で終了。それ以外は T2 に進む。
T2: ロールバック機能付きデータマイグレーション (≤6kトークン)
データ変換を伴う拡張マイグレーション:
-
データマイグレーションパターン アクセス日時: 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') -
ロールバック安全性パターン
- べき等性: マイグレーションを複数回安全に実行できることを確認
- チェックポイント: 破壊的操作前に検証クエリを追加
- バックアップトリガー: データマイグレーション用の一時バックアップテーブルを作成
- ドライランモード: 変更をプレビューするためのコメント付きSELECT文を含む
-
検証テスト アクセス日時: 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であるべき -
データベース固有の考慮事項
PostgreSQL アクセス日時: 2025-10-26T03:51:54-04:00
ALTER TABLE ... SET NOT NULLをCHECK制約で先に使用- インデックス作成には
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トークン)
本番システム向けの高度なパターン:
-
拡張/縮小パターン アクセス日時: 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') -
オンラインインデックス作成 アクセス日時: 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; -
シャドウテーブルパターン (複雑な変換向け)
# マイグレーション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') -
展開ガイドテンプレート
## 展開手順 ### マイグレーション前 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. ロールバックが失敗した場合はバックアップから復旧 -
ブルーグリーンデータベースマイグレーション アクセス日時: 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_tool、database、migration_type、downtime_allowed、migration_script、rollback_script、validation_tests、deployment_guide、timestamp
安全性保証:
- すべての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):
- Liquibase Change Types - DDL/DML操作
- Flyway SQL Migrations - バージョン管理されたマイグレーション
- Alembic Operations Reference - Pythonマイグレーション API
- PostgreSQL ALTER TABLE - DDL構文
- MySQL Online DDL - ゼロダウンタイム操作
- SQL Server Online Index Operations - オンラインDDL
マイグレーションパターン:
- Expand/Contract Pattern - ゼロダウンタイムスキーマ進化
- Blue-Green Deployments - データベースマイグレーション戦略
- Database Refactoring - データベースリファクタリングパターンカタログ
ベストプラクティス:
- Flyway Best Practices - マイグレーションバージョニングと命名
- Alembic Tutorial - 自動生成対手動マイグレーション
- PostgreSQL Wiki: Don't Do This - 回避すべきアンチパターン
ツール比較:
- Liquibase vs Flyway - 機能比較
- Schema Migration Tools Comparison - マルチツールベンチマーク
ライセンス: Apache-2.0(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- williamzujkowski
- ライセンス
- Apache-2.0
- 最終更新
- 2026/4/18
Source: https://github.com/williamzujkowski/cognitive-toolworks / ライセンス: Apache-2.0