db-migration
Use when setting up Alembic migrations or making database schema changes. Triggers for: initializing Alembic, generating migrations, applying upgrades, rolling back changes, or creating data migrations. NOT for: raw SQL execution outside migration context or non-database schema updates.
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o db-migration.zip https://jpskill.com/download/17380.zip && unzip -o db-migration.zip && rm db-migration.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/17380.zip -OutFile "$d\db-migration.zip"; Expand-Archive "$d\db-migration.zip" -DestinationPath $d -Force; ri "$d\db-migration.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
db-migration.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
db-migrationフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 2
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
[Skill 名] db-migration
データベースマイグレーションスキル
安全なスキーマの進化とロールバック機能を備えた、SQLModel/FastAPI プロジェクト向けの高度な Alembic マイグレーション管理。
クイックリファレンス
| コマンド | 目的 |
|---|---|
alembic init alembic |
プロジェクトで Alembic を初期化します |
alembic revision --autogenerate -m "message" |
モデルの変更からマイグレーションを生成します |
alembic revision -m "message" |
空のマイグレーションを手動で作成します |
alembic upgrade head |
保留中のすべてのマイグレーションを適用します |
alembic upgrade +1 |
マイグレーションを一度に 1 つずつ適用します |
alembic downgrade -1 |
最後のマイグレーションをロールバックします |
alembic downgrade base |
すべてのマイグレーションをロールバックします |
alembic current |
現在のリビジョンを表示します |
alembic history |
マイグレーションの履歴を表示します |
初期設定
1. Alembic の初期化
alembic init alembic
2. alembic.ini の設定
# alembic.ini
sqlalchemy.url = driver://user:pass@localhost/dbname
file_template = %%(year)s_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d_%%(rev)s_%%(slug)s
timezone = UTC
3. SQLModel 用の env.py の設定
# alembic/env.py
from logging.config import fileConfig
from sqlalchemy import pool
from sqlalchemy.engine import Connection
from alembic.runtime.migration import MigrationContext
from sqlmodel import SQLModel, create_engine
from myapp.models import * # すべての SQLModel クラスをインポート
config = context.config
config.set_main_option("sqlalchemy.url", "postgresql://user:pass@localhost/dbname")
target_metadata = SQLModel.metadata
def run_migrations_offline() -> None:
"""'offline' モードでマイグレーションを実行します。"""
url = config.get_main_option("sqlalchemy.url")
context.configure(
url=url,
target_metadata=target_metadata,
literal_binds=True,
dialect_opts={"paramstyle": "named"},
)
with context.begin_transaction():
context.run_migrations()
def run_migrations_online() -> None:
"""'online' モードでマイグレーションを実行します。"""
connectable = create_engine(
config.get_main_option("sqlalchemy.url"),
poolclass=pool.NullPool,
)
with connectable.connect() as connection:
context.configure(
connection=connection,
target_metadata=target_metadata,
)
with context.begin_transaction():
context.run_migrations()
if context.is_offline_mode():
run_migrations_offline()
else:
run_migrations_online()
マイグレーションの生成
モデルの変更からの自動生成
# モデルの差分に基づいてマイグレーションを自動的に生成します
alembic revision --autogenerate -m "add_fees_table"
# 特定のリビジョン範囲を指定する場合
alembic revision --autogenerate -m "add_user_email" --rev-id=abc123
手動マイグレーション
# 手動で変更するための空のマイグレーションを作成します
alembic revision -m "add_status_column"
例: 新しいテーブルの追加
# alembic/versions/2024_01_15_1200_add_fees_table.py
"""add_fees_table
Revision ID: abc123
Revises: def456
Create Date: 2024-01-15 12:00:00.000000
"""
from alembic import op
import sqlalchemy as sa
from sqlmodel import SQLModel
# リビジョン識別子
revision = 'abc123'
down_revision = 'def456'
branch_labels = None
depends_on = None
def upgrade() -> None:
op.create_table(
'fees',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('student_id', sa.Integer(), nullable=False),
sa.Column('amount', sa.Numeric(precision=10, scale=2), nullable=False),
sa.Column('status', sa.String(length=20), nullable=False, default='pending'),
sa.Column('due_date', sa.DateTime(), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=False, server_default=sa.func.now()),
sa.Column('updated_at', sa.DateTime(), nullable=False, server_default=sa.func.now()),
sa.PrimaryKeyConstraint('id'),
sa.ForeignKeyConstraint(['student_id'], ['students.id']),
)
op.create_index('ix_fees_student_id', 'fees', ['student_id'])
op.create_index('ix_fees_status', 'fees', ['status'])
def downgrade() -> None:
op.drop_index('ix_fees_status', table_name='fees')
op.drop_index('ix_fees_student_id', table_name='fees')
op.drop_table('fees')
例: カラムの追加
# alembic/versions/2024_01_16_0900_add_fees_description.py
"""add_fees_description
Revision ID: ghi789
Revises: abc123
Create Date: 2024-01-16 09:00:00.000000
"""
from alembic import op
def upgrade() -> None:
op.add_column('fees', sa.Column('description', sa.Text(), nullable=True))
def downgrade() -> None:
op.drop_column('fees', 'description')
マイグレーションの適用
標準的なアップグレード
# 最新のリビジョンにアップグレードします
alembic upgrade head
# 一度に 1 ステップずつアップグレードします
alembic upgrade +1
# 特定のリビジョンにアップグレードします
alembic upgrade abc123
ドライラン (何が起こるかを確認)
# 適用せずに保留中のマイグレーションを表示します
alembic show heads
alembic history --verbose
ロールバック (ダウングレード)
# 1 つのマイグレーションをロールバックします
alembic downgrade -1
# 特定のリビジョンにロールバックします
alembic downgrade abc123
# すべてのマイグレーションをロールバックします (空のデータベース)
alembic downgrade base
安全なダウングレードパターン
def downgrade() -> None:
# 常にテーブルの前にインデックスを削除します
op.drop_index('ix_fees_status', table_name='fees')
op.drop_index('ix_fees_student_id', table_name='fees')
# テーブルの前に外部キーを削除します
op.drop_constraint('fees_student_id_fkey', 'fees', type_='foreignkey')
op.drop_table('fees')
データマイグレーション
例: バッチ更新によるデータマイグレーション
# alembic/versions/2024_01_17_1400_update_fees_status.py
"""update_fees_status_values
Revision ID: jkl012
Revises: ghi789
Create Date: 2024-01-17 14:00:00.000000
"""
from alembic import op
from sqlalchemy import text
def upgrade() -> None:
# 既存のレコードを更新します
op.execute(
text("UPDATE fees SET status = 'pending' WHERE status = 'unpaid'")
) 📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
Database Migration Skill
Expert Alembic migration management for SQLModel/FastAPI projects with safe schema evolution and rollback capabilities.
Quick Reference
| Command | Purpose |
|---|---|
alembic init alembic |
Initialize Alembic in project |
alembic revision --autogenerate -m "message" |
Generate migration from model changes |
alembic revision -m "message" |
Create empty migration manually |
alembic upgrade head |
Apply all pending migrations |
alembic upgrade +1 |
Apply one migration at a time |
alembic downgrade -1 |
Rollback last migration |
alembic downgrade base |
Rollback all migrations |
alembic current |
Show current revision |
alembic history |
Show migration history |
Initial Setup
1. Initialize Alembic
alembic init alembic
2. Configure alembic.ini
# alembic.ini
sqlalchemy.url = driver://user:pass@localhost/dbname
file_template = %%(year)s_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d_%%(rev)s_%%(slug)s
timezone = UTC
3. Configure env.py for SQLModel
# alembic/env.py
from logging.config import fileConfig
from sqlalchemy import pool
from sqlalchemy.engine import Connection
from alembic.runtime.migration import MigrationContext
from sqlmodel import SQLModel, create_engine
from myapp.models import * # Import all SQLModel classes
config = context.config
config.set_main_option("sqlalchemy.url", "postgresql://user:pass@localhost/dbname")
target_metadata = SQLModel.metadata
def run_migrations_offline() -> None:
"""Run migrations in 'offline' mode."""
url = config.get_main_option("sqlalchemy.url")
context.configure(
url=url,
target_metadata=target_metadata,
literal_binds=True,
dialect_opts={"paramstyle": "named"},
)
with context.begin_transaction():
context.run_migrations()
def run_migrations_online() -> None:
"""Run migrations in 'online' mode."""
connectable = create_engine(
config.get_main_option("sqlalchemy.url"),
poolclass=pool.NullPool,
)
with connectable.connect() as connection:
context.configure(
connection=connection,
target_metadata=target_metadata,
)
with context.begin_transaction():
context.run_migrations()
if context.is_offline_mode():
run_migrations_offline()
else:
run_migrations_online()
Generating Migrations
Auto-Generate from Model Changes
# Generate migration automatically based on model diffs
alembic revision --autogenerate -m "add_fees_table"
# With specific revision range
alembic revision --autogenerate -m "add_user_email" --rev-id=abc123
Manual Migration
# Create empty migration for manual changes
alembic revision -m "add_status_column"
Example: Adding a New Table
# alembic/versions/2024_01_15_1200_add_fees_table.py
"""add_fees_table
Revision ID: abc123
Revises: def456
Create Date: 2024-01-15 12:00:00.000000
"""
from alembic import op
import sqlalchemy as sa
from sqlmodel import SQLModel
# revision identifiers
revision = 'abc123'
down_revision = 'def456'
branch_labels = None
depends_on = None
def upgrade() -> None:
op.create_table(
'fees',
sa.Column('id', sa.Integer(), nullable=False),
sa.Column('student_id', sa.Integer(), nullable=False),
sa.Column('amount', sa.Numeric(precision=10, scale=2), nullable=False),
sa.Column('status', sa.String(length=20), nullable=False, default='pending'),
sa.Column('due_date', sa.DateTime(), nullable=False),
sa.Column('created_at', sa.DateTime(), nullable=False, server_default=sa.func.now()),
sa.Column('updated_at', sa.DateTime(), nullable=False, server_default=sa.func.now()),
sa.PrimaryKeyConstraint('id'),
sa.ForeignKeyConstraint(['student_id'], ['students.id']),
)
op.create_index('ix_fees_student_id', 'fees', ['student_id'])
op.create_index('ix_fees_status', 'fees', ['status'])
def downgrade() -> None:
op.drop_index('ix_fees_status', table_name='fees')
op.drop_index('ix_fees_student_id', table_name='fees')
op.drop_table('fees')
Example: Adding a Column
# alembic/versions/2024_01_16_0900_add_fees_description.py
"""add_fees_description
Revision ID: ghi789
Revises: abc123
Create Date: 2024-01-16 09:00:00.000000
"""
from alembic import op
def upgrade() -> None:
op.add_column('fees', sa.Column('description', sa.Text(), nullable=True))
def downgrade() -> None:
op.drop_column('fees', 'description')
Applying Migrations
Standard Upgrade
# Upgrade to latest revision
alembic upgrade head
# Upgrade one step at a time
alembic upgrade +1
# Upgrade to specific revision
alembic upgrade abc123
Dry Run (Check What Would Happen)
# Show pending migrations without applying
alembic show heads
alembic history --verbose
Rollback (Downgrade)
# Rollback one migration
alembic downgrade -1
# Rollback to specific revision
alembic downgrade abc123
# Rollback all migrations (empty database)
alembic downgrade base
Safe Downgrade Pattern
def downgrade() -> None:
# Always drop indexes before table
op.drop_index('ix_fees_status', table_name='fees')
op.drop_index('ix_fees_student_id', table_name='fees')
# Drop foreign keys before table
op.drop_constraint('fees_student_id_fkey', 'fees', type_='foreignkey')
op.drop_table('fees')
Data Migrations
Example: Data Migration with Batch Update
# alembic/versions/2024_01_17_1400_update_fees_status.py
"""update_fees_status_values
Revision ID: jkl012
Revises: ghi789
Create Date: 2024-01-17 14:00:00.000000
"""
from alembic import op
from sqlalchemy import text
def upgrade() -> None:
# Update existing records
op.execute(
text("UPDATE fees SET status = 'pending' WHERE status = 'unpaid'")
)
def downgrade() -> None:
# Revert status values
op.execute(
text("UPDATE fees SET status = 'unpaid' WHERE status = 'pending'")
)
Example: Enum Migration
def upgrade() -> None:
# Add new enum type
op.execute("CREATE TYPE fee_status_new AS ENUM ('pending', 'paid', 'overdue', 'waived')")
# Copy data to new type
op.execute("ALTER TABLE fees ALTER COLUMN status TYPE fee_status_new USING status::text::fee_status_new")
# Drop old type
op.execute("DROP TYPE fee_status_old")
def downgrade() -> None:
# Reverse the process
op.execute("ALTER TABLE fees ALTER COLUMN status TYPE VARCHAR(20)")
op.execute("DROP TYPE fee_status_new")
Quality Checklist
- [ ] Data migrations: Handle existing data when modifying columns/tables
- [ ] Test migrations: Run
alembic upgradethenalembic downgradein test - [ ] Idempotent operations: up() and down() can run multiple times safely
- [ ] No data loss: Use
DROP TABLE IF EXISTS,DROP COLUMN IF EXISTS - [ ] Indexes created: Include index creation in upgrade, drop in downgrade
- [ ] Foreign keys: Handle constraint ordering (create before, drop after)
- [ ] Backwards compatible: Don't break existing application during migration
Integration with Other Skills
| Skill | Integration Point |
|---|---|
@sqlmodel-crud |
Model changes trigger migrations |
@fastapi-app |
Migrations run at startup or via CLI |
@jwt-auth |
May need to handle auth during migrations |
Migration Best Practices
1. Always Generate Before Manual Edit
alembic revision --autogenerate -m "describe_change"
# Then review and edit the generated file
2. Review Generated Migrations
# Check that:
# - Column types match SQLModel definitions
# - Foreign key constraints are correct
# - Indexes are appropriate
# - Default values are set
3. Test Migration Cycle
# In test environment
alembic downgrade base
alembic upgrade head
# Verify all data is intact
4. Handle Long-Running Migrations
# For large tables, use batch updates
def upgrade():
op.execute("""
UPDATE fees SET status = 'pending'
WHERE status IS NULL
LIMIT 10000
""")
Directory Structure
project/
├── alembic/
│ ├── env.py # Migration configuration
│ ├── script.py.mako # Template for new migrations
│ ├── README # Alembic documentation
│ └── versions/
│ ├── 2024_01_15_1200_add_fees_table.py
│ └── 2024_01_16_0900_add_fees_description.py
├── myapp/
│ └── models.py # SQLModel definitions
└── alembic.ini # Alembic configuration 同梱ファイル
※ ZIPに含まれるファイル一覧。`SKILL.md` 本体に加え、参考資料・サンプル・スクリプトが入っている場合があります。
- 📄 SKILL.md (9,165 bytes)
- 📎 scripts/verify.py (1,902 bytes)