Claude-skill-registry-data migration-database
This skill should be used when working with database migrations in SQLModel-based projects. Trigger when user asks to create migrations for new/modified models, generate database schema changes, or apply migrations. Enforces SQLModel as single source of truth and automatic migration generation only.
git clone https://github.com/majiayu000/claude-skill-registry-data
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry-data "$T" && mkdir -p ~/.claude/skills && cp -r "$T/data/migration-database" ~/.claude/skills/majiayu000-claude-skill-registry-data-migration-database && rm -rf "$T"
data/migration-database/SKILL.mdDatabase Migration (SQLModel + Alembic)
Overview
Automate database migration workflows for SQLModel-based projects using Alembic. This skill enforces strict rules: SQLModel models are the single source of truth, migrations are generated automatically only (never manual), and all migrations must include
import sqlmodel for proper functioning.
When to Use This Skill
Trigger this skill when the user requests:
- "Create a migration for the new User model"
- "Generate migration after I updated Task fields"
- "I added a column to Topic, make a migration"
- "Apply pending migrations to the database"
- Any task involving database schema changes in SQLModel projects
Core Principles
1. SQLModel as Single Source of Truth
- NEVER modify database schema directly (via SQL, pgAdmin, psql, etc.)
- ALWAYS modify SQLModel model classes first, then generate migrations
- Database must reflect SQLModel models exactly
2. Automatic Generation Only
- ALWAYS use
to generate migrationsjust alembic-auto -m "description" - NEVER create empty manual migrations
- NEVER write custom SQL without explicit user approval
3. Required Import Fix
Alembic often omits
import sqlmodel, causing errors with SQLModel types. ALWAYS add this import after generation.
Workflow
Step 1: Pre-Generation Safety Checks
Before generating any migration, verify prerequisites:
-
Check PostgreSQL is running:
docker compose ps postgresIf not running, start it:
docker compose up -d postgres -
Verify model imports in
:backend/app/models/__init__.py- Read the file and confirm new/modified models are imported
- Add missing imports if needed
-
Type check for syntax errors:
just typecheckFix any errors before proceeding
Step 2: Generate Migration
Use the automatic migration generation command:
just alembic-auto -m "descriptive message"
Message conventions:
- ✅
"add User table with authentication fields" - ✅
"update Task: add priority and status fields" - ✅
"add foreign key relationship Task.user_id → User.id" - ❌
(too vague)"migration" - ❌
(not descriptive)"changes"
Step 3: Post-Generation Fixes (MANDATORY)
Critical step - never skip this:
-
Locate the migration file:
- Alembic prints the path in output:
backend/alembic/versions/{revision_id}_{slug}.py - Example:
backend/alembic/versions/abc123def456_add_user_table.py
- Alembic prints the path in output:
-
Read the migration file completely
-
Check for
:import sqlmodel- Look in the import section (after
)import sqlalchemy as sa - If
is missing, add it:import sqlmodel
"""add User table Revision ID: abc123def456 Revises: previous_revision Create Date: 2024-01-01 12:00:00.000000 """ from alembic import op import sqlalchemy as sa import sqlmodel # ← ADD THIS IF MISSING # revision identifiers revision = 'abc123def456' down_revision = 'previous_revision' branch_labels = None depends_on = None - Look in the import section (after
-
Validate migration operations:
- Review
andupgrade()
functionsdowngrade() - Check operations match expected model changes
- Warn user about destructive operations (DROP COLUMN, DROP TABLE)
- Review
Step 4: Present Migration for Review
Provide clickable file link for user review:
- Provide file path as clickable link (format:
)backend/alembic/versions/{filename}.py:1 - Summarize key changes from
andupgrade()
functionsdowngrade() - Call out any potentially destructive operations (DROP COLUMN, DROP TABLE)
- Wait for explicit user confirmation before applying
DO NOT paste full migration contents in chat - provide file link only.
Step 5: Apply Migration (After Confirmation Only)
Only proceed after user explicitly confirms:
just alembic-up
NEVER apply migrations without user approval.
Common Scenarios
Creating New Model
User adds a new SQLModel in
backend/app/models/:
- Verify model is imported in
backend/app/models/__init__.py - Run pre-generation checks (PostgreSQL, type check)
- Generate:
just alembic-auto -m "add {ModelName} table" - Read migration file
- Add
if missingimport sqlmodel - Provide clickable file link and summarize changes
- Apply after confirmation:
just alembic-up
Modifying Existing Model
User changes fields in an existing SQLModel:
- Run pre-generation checks
- Generate:
just alembic-auto -m "update {ModelName}: {change description}" - Read migration file
- Add
if missingimport sqlmodel - Provide clickable file link and summarize changes
- Apply after confirmation:
just alembic-up
Multiple Model Changes
User modifies several models at once:
- Group related changes into logical units
- Generate one migration per logical change (preferred)
- OR generate single migration for all changes if closely related
- Follow standard workflow for each migration
Error Handling
"NameError: name 'sqlmodel' is not defined"
Cause: Missing
import sqlmodel in migration
Fix: Edit migration file, add import sqlmodel to imports
"Target database is not up to date"
Cause: Pending unapplied migrations exist Fix: Run
just alembic-up to apply pending migrations before generating new ones
"Can't proceed with autogenerate"
Cause: Models not imported or database inaccessible Fix:
- Check
for missing importsbackend/app/models/__init__.py - Verify:
docker compose ps postgres - Check database connection settings
Extending SQLModel
⚠️ Important: Always prefer native SQLModel features first. Only use SQLAlchemy extensions when SQLModel doesn't support the feature.
When SQLModel lacks native support for a feature (e.g., PostgreSQL JSON/ARRAY, CHECK constraints, composite unique constraints), extend via SQLAlchemy:
from sqlmodel import Field, Column from sqlalchemy import JSON, CheckConstraint class Model(SQLModel, table=True): # PostgreSQL JSON type data: dict = Field(sa_column=Column(JSON, nullable=False)) # CHECK constraint rating: int = Field( sa_column=Column(Integer, CheckConstraint('rating >= 1 AND rating <= 5')) )
See
references/sqlmodel-migration-rules.md → "Extending SQLModel with SQLAlchemy" for full examples.
Safety Rules (STRICT)
Forbidden Without User Approval
- Creating manual migrations (empty migrations)
- Modifying database schema directly (SQL commands, GUI tools)
- Editing already-applied migrations (in
)alembic_version - Running custom SQL in migrations
- Applying migrations without providing file link and summary first
- Removing
from migrationsimport sqlmodel
Always Required
- Generate migrations using
just alembic-auto - Add
to every migration if missingimport sqlmodel - Provide clickable file link and summarize changes before applying
- Wait for explicit user confirmation before
alembic-up - Verify PostgreSQL is running before generation
References
For detailed information about SQLModel types, migration patterns, and comprehensive rules, refer to:
- Complete migration rules and type mappingsreferences/sqlmodel-migration-rules.md
Quick Reference
# Pre-generation checks docker compose ps postgres # Verify DB is running just typecheck # Check for syntax errors # Generate migration just alembic-auto -m "description" # Create migration # Apply migration (after review) just alembic-up # Apply to database # Common debugging docker compose logs postgres # Check DB logs docker compose restart postgres # Restart if needed
Workflow Summary
- ✅ Pre-checks: PostgreSQL running, models imported, no syntax errors
- ✅ Generate:
just alembic-auto -m "description" - ✅ Read migration file completely
- ✅ Add
if missingimport sqlmodel - ✅ Provide file link (format:
) and summarize changesfile.py:1 - ⏸️ WAIT for user confirmation
- ✅ Apply:
(only after confirmation)just alembic-up
Remember: SQLModel is truth, autogenerate only, always add
import sqlmodel, provide file links (not full contents), never apply without approval.