Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

Database Migration Skill

ASecurity

Database schema evolution with Prisma, Alembic, Django — workflows, rollback, zero-downtime, seed data, migration testing.

6 stars
0 votes
0 copies
0 views
Added 9/20/2026
databasestypescriptpythongobashsqlnodefastapidjangoflaskdocker

Works with

cliapi

Security Analysis

A96/100
mediumInstalls packages at runtime which could introduce malicious dependencies

Scanned 9/20/2026

Install to Claude Code

$npx -y skills add darellchua2/opencode-config-template --skill database-migration-skill --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Database Migration Skill?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Database Migration Skill
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/darellchua2-database-migration-skill/badge)](https://www.skillsdirectory.com/skills/darellchua2-database-migration-skill)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
SKILL.md
---
name: database-migration-skill
description: >-
  Database schema evolution with Prisma, Alembic, Django — workflows, rollback,
  zero-downtime, seed data, migration testing.
license: Apache-2.0
compatibility: opencode
category: DevOps
---

## What I do

I help you manage database schema changes safely and repeatably:

1. **Schema Evolution**: Design schemas that change safely over time
2. **Prisma Migrations**: TypeScript/Node.js migration workflow
3. **Alembic Migrations**: Python/SQLAlchemy migration workflow
4. **Django Migrations**: Django ORM migration workflow
5. **Rollback Strategies**: Safe rollback planning and execution
6. **Zero-Downtime Migrations**: Techniques for production-safe schema changes
7. **Seed Data**: Manage test and development seed data
8. **Migration Testing**: Verify migrations work correctly before production

## When to use me

Use this skill when:
- Creating or modifying database schema
- Setting up a migration system for a new project
- Writing reversible migrations
- Planning zero-downtime production migrations
- Managing seed data for development/testing
- Debugging failed migrations
- Setting up migration CI checks
- Converting between migration tools

## Related Skills

- **performance-optimization-skill**: Handles runtime query profiling and optimization. This skill handles schema lifecycle. Index optimization can overlap — this skill handles index creation in migrations, performance skill handles query analysis.
- **python-backend-skill**: FastAPI/Django/Flask project patterns that use these migration tools.
- **docker-containerization-skill**: Database containers in compose configurations.

---

## Step 1: Migration Principles

### Rules for Safe Migrations

1. **Never modify an existing migration** that has been applied
2. **Always make migrations reversible** (with rare exceptions)
3. **Test migrations against production-like data** before deploying
4. **Use separate migrations** for additive and destructive changes
5. **Prefer additive changes** — add new columns/tables before removing old ones

### Migration Categories

| Type | Risk | Reversibility | Example |
|------|------|---------------|---------|
| Additive (create table, add column) | Low | Easy | Add `phone` column to `users` |
| Add constraint | Medium | Moderate | Add NOT NULL, foreign key |
| Add index | Low | Easy | Add index on `users.email` |
| Rename column/table | Medium | Hard | Rename `name` to `full_name` |
| Remove column/table | High | Hard (data loss) | Drop `legacy_field` |
| Change column type | High | Hard | Change `int` to `bigint` |
| Data migration | Medium | Moderate | Backfill new column from old data |

---

## Step 2: Prisma (TypeScript/Node.js)

### Setup

```prisma
datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

generator client {
  provider = "prisma-client-js"
}

model User {
  id        String   @id @default(cuid())
  email     String   @unique
  name      String
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
  posts     Post[]
}

model Post {
  id        String   @id @default(cuid())
  title     String
  content   String?
  published Boolean  @default(false)
  author    User     @relation(fields: [authorId], references: [id])
  authorId  String
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}
```

### Workflow

```bash
npx prisma migrate dev --name init          # Create and apply migration
npx prisma migrate dev --name add-phone     # New migration
npx prisma migrate deploy                   # Apply pending migrations (production)
npx prisma migrate status                   # Check migration state
npx prisma migrate reset                    # Reset database (development only)
npx prisma db push                          # Push schema without migration (prototyping)
```

### Custom Migration SQL

```sql
-- prisma/migrations/20240115_add_user_role/migration.sql
ALTER TABLE "User" ADD COLUMN "role" TEXT NOT NULL DEFAULT 'user';

UPDATE "User" SET "role" = 'admin' WHERE email IN ('admin@example.com');

CREATE INDEX "User_role_idx" ON "User"("role");
```

### Seed Data

```typescript
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()

async function main() {
  await prisma.user.upsert({
    where: { email: 'admin@example.com' },
    update: {},
    create: { email: 'admin@example.com', name: 'Admin', role: 'admin' },
  })
}

main()
  .then(() => prisma.$disconnect())
  .catch((e) => { console.error(e); process.exit(1) })
```

---

## Step 3: Alembic (Python/SQLAlchemy)

### Setup

```bash
pip install alembic
alembic init alembic
```

### Configuration

```python
from alembic.config import Config
from sqlalchemy import create_engine
import os

config = Config("alembic.ini")
config.set_main_option("sqlalchemy.url", os.environ["DATABASE_URL"])
```

### Create Migration

```bash
alembic revision --autogenerate -m "add user phone column"
alembic upgrade head
alembic downgrade -1
alembic history --verbose
alembic current
```

### Manual Migration

```python
def upgrade() -> None:
    op.add_column('users', sa.Column('phone', sa.String(20), nullable=True))
    op.create_index('ix_users_phone', 'users', ['phone'])

def downgrade() -> None:
    op.drop_index('ix_users_phone', table_name='users')
    op.drop_column('users', 'phone')
```

### Safe Column Type Change (Two-Phase)

```python
def upgrade() -> None:
    op.add_column('orders', sa.Column('amount_new', sa.BigInteger(), nullable=True))

    op.execute("""
        UPDATE orders SET amount_new = amount::bigint
    """)

    op.alter_column('orders', 'amount_new', nullable=False)
    op.drop_column('orders', 'amount')
    op.alter_column('orders', 'amount_new', new_column_name='amount')
```

---

## Step 4: Django Migrations

### Workflow

```bash
python manage.py makemigrations              # Detect model changes
python manage.py migrate                     # Apply all pending migrations
python manage.py migrate app_name 0003       # Migrate to specific version
python manage.py migrate app_name zero       # Rollback all migrations for app
python manage.py showmigrations              # Show migration status
python manage.py sqlmigrate app_name 0003    # Show SQL for migration
```

### Empty Migration (for data migrations)

```bash
python manage.py makemigrations --empty users --name populate_roles
```

```python
from django.db import migrations

def populate_roles(apps, schema_editor):
    User = apps.get_model('users', 'User')
    for user in User.objects.filter(is_superuser=True):
        user.role = 'admin'
        user.save(update_fields=['role'])

class Migration(migrations.Migration):
    dependencies = [
        ('users', '0004_add_role_field'),
    ]

    operations = [
        migrations.RunPython(populate_roles, migrations.RunPython.noop),
    ]
```

---

## Step 5: Zero-Downtime Migration Strategy

### Two-Phase Migration Pattern

**Phase 1: Add new structure (non-breaking)**

```sql
ALTER TABLE users ADD COLUMN full_name VARCHAR(255);
CREATE INDEX CONCURRENTLY users_full_name_idx ON users(full_name);
```

- Application reads old column, writes to both
- Deploy application code that populates `full_name` from `name`

**Phase 2: Remove old structure (after full rollout)**

```sql
-- Only after ALL instances are reading from full_name
ALTER TABLE users DROP COLUMN name;
```

### Checklist for Production Migrations

- [ ] Migration tested against production-like data volume
- [ ] Rollback migration prepared and tested
- [ ] Data backup verified
- [ ] Index creation uses `CONCURRENTLY` (PostgreSQL) or equivalent
- [ ] Long-running migrations run during low-traffic period
- [ ] Application code deployed that handles both old and new schema
- [ ] Migration run in a transaction where possible (DDL permitting)

### PostgreSQL-Specific

```sql
CREATE INDEX CONCURRENTLY users_email_idx ON users(email);
ALTER TABLE users ADD COLUMN phone VARCHAR(20);
ALTER TABLE users ADD CONSTRAINT users_phone_check CHECK (phone ~ '^\+?[0-9]{10,15}$');
```

---

## Step 6: Migration Testing

### CI Integration

```yaml
name: Migration Check
on: [push]
jobs:
  migrate:
    runs-on: ubuntu-latest
    services:
      postgres:
        image: postgres:16
        env:
          POSTGRES_DB: test_db
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
          --health-retries 5
    steps:
      - uses: actions/checkout@v4
      - name: Test migrations
        run: |
          alembic upgrade head
          alembic downgrade base
          alembic upgrade head
```

### Test Checklist

| Test | Purpose |
|------|---------|
| Forward migration | Verify migration applies cleanly |
| Rollback migration | Verify downgrade works |
| Forward-rollback-forward | Verify idempotency |
| With seed data | Verify data integrity |
| With production-like volume | Verify performance |
| Concurrent access | Verify no deadlocks |

---

## Step 7: Migration Pitfalls

### `bulk_insert` JSONB with asyncpg

**Learning**: `migration-jsonb-dicts`

When using Alembic `bulk_insert` with asyncpg, JSONB columns require Python dicts — not JSON strings. asyncpg does not auto-serialize `json.dumps()` output; it expects native Python types.

```python
import json

# WRONG — JSON string passed to asyncpg JSONB column
op.bulk_insert(
    sa.table("nodes"),
    [{"id": "n1", "config": json.dumps({"key": "val"})}],
)
# asyncpg error: expected dict, got str

# CORRECT — native Python dict
op.bulk_insert(
    sa.table("nodes"),
    [{"id": "n1", "config": {"key": "val"}}],
)
```

> **Cross-reference**: This pitfall is also documented in **python-backend-skill** Step 8.

Attribution

darellchua2darellchua2
View sourceMore from darellchua2 →
SSkills DirectorySkills Directory

Your tool, in front of Claude Code builders.

3 founder slots · $299/mo · GSC-verified traffic · sponsors can never buy grades.

See placements

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Your tool, in front of Claude Code builders.

3 founder slots · $299/mo · GSC-verified traffic · sponsors can never buy grades.

See placements

Related Skills

Mysql Best Practices

MySQL development best practices for schema design, query optimization, and database administration

2481 votes

Clickhouse Io

ClickHouse数据库模式、查询优化、分析和数据工程最佳实践,适用于高性能分析工作负载。

2456590 votes

Jpa Patterns

Spring Boot中的JPA/Hibernate实体设计、关系、查询优化、事务、审计、索引、分页和连接池模式。

2456590 votes

Postgres Patterns

基于Supabase最佳实践的PostgreSQL数据库模式,用于查询优化、架构设计、索引和安全。

2456590 votes

V3 Memory Unification

Unify 6+ memory systems into AgentDB with HNSW indexing for 150x-12,500x search improvements. Implements ADR-006 (Unified Memory Service) and ADR-009 (Hybrid Memory Backend).

701370 votes
View all in databases →