database-migration
Safe patterns for evolving database schemas in production with decision trees and troubleshooting guidance.
What this skill does
# Database Migration
Safe patterns for evolving database schemas in production.
## Migration Principles
1. **Backward compatible** - New code works with old schema
2. **Reversible** - Can rollback if needed
3. **Tested** - Verify on staging before production
4. **Incremental** - Small changes, not big-bang
5. **Zero downtime** - No service interruption
## Safe Migration Pattern
### Phase 1: Add New (Compatible)
```sql
-- Add new column (nullable initially)
ALTER TABLE users ADD COLUMN full_name VARCHAR(255) NULL;
-- Deploy new code that writes to both old and new
UPDATE users SET full_name = CONCAT(first_name, ' ', last_name);
```
### Phase 2: Migrate Data
```sql
-- Backfill existing data
UPDATE users
SET full_name = CONCAT(first_name, ' ', last_name)
WHERE full_name IS NULL;
```
### Phase 3: Make Required
```sql
-- Make column required
ALTER TABLE users ALTER COLUMN full_name SET NOT NULL;
```
### Phase 4: Remove Old (After New Code Deployed)
```sql
-- Remove old columns
ALTER TABLE users DROP COLUMN first_name;
ALTER TABLE users DROP COLUMN last_name;
```
## Common Migrations
### Adding Index
```sql
-- Create index concurrently (PostgreSQL)
CREATE INDEX CONCURRENTLY idx_users_email ON users(email);
```
### Renaming Column
```sql
-- Phase 1: Add new column
ALTER TABLE users ADD COLUMN email_address VARCHAR(255);
-- Phase 2: Copy data
UPDATE users SET email_address = email;
-- Phase 3: Drop old column (after deploy)
ALTER TABLE users DROP COLUMN email;
```
### Changing Column Type
```sql
-- Phase 1: Add new column with new type
ALTER TABLE products ADD COLUMN price_cents INTEGER;
-- Phase 2: Migrate data
UPDATE products SET price_cents = CAST(price * 100 AS INTEGER);
-- Phase 3: Drop old column
ALTER TABLE products DROP COLUMN price;
ALTER TABLE products RENAME COLUMN price_cents TO price;
```
### Adding Foreign Key
```sql
-- Add column first
ALTER TABLE orders ADD COLUMN user_id INTEGER NULL;
-- Populate data
UPDATE orders SET user_id = (
SELECT id FROM users WHERE users.email = orders.user_email
);
-- Add foreign key
ALTER TABLE orders
ADD CONSTRAINT fk_orders_users
FOREIGN KEY (user_id) REFERENCES users(id);
```
## Migration Tools
### Python (Alembic)
```python
# Generate migration
alembic revision --autogenerate -m "add user full_name"
# Apply migration
alembic upgrade head
# Rollback
alembic downgrade -1
```
### JavaScript (Knex)
```javascript
// Create migration
knex migrate:make add_full_name
// Apply migrations
knex migrate:latest
// Rollback
knex migrate:rollback
```
### Rails
```ruby
# Generate migration
rails generate migration AddFullNameToUsers full_name:string
# Run migrations
rails db:migrate
# Rollback
rails db:rollback
```
## Testing Migrations
```python
def test_migration_forward_backward():
# Apply migration
apply_migration("add_full_name")
# Verify schema
assert column_exists("users", "full_name")
# Rollback
rollback_migration()
# Verify rollback
assert not column_exists("users", "full_name")
```
## Dangerous Operations
### ❌ Avoid in Production
```sql
-- Locks table for long time
ALTER TABLE users ADD COLUMN email VARCHAR(255) NOT NULL;
-- Can't rollback
DROP TABLE old_users;
-- Breaks existing code immediately
ALTER TABLE users DROP COLUMN email;
```
### ✅ Safe Alternatives
```sql
-- Add as nullable first
ALTER TABLE users ADD COLUMN email VARCHAR(255) NULL;
-- Rename instead of drop
ALTER TABLE old_users RENAME TO archived_users;
-- Keep old column until new code deployed
-- (multi-phase approach)
```
## Rollback Strategy
```sql
-- Every migration needs DOWN
-- UP
ALTER TABLE users ADD COLUMN full_name VARCHAR(255);
-- DOWN
ALTER TABLE users DROP COLUMN full_name;
```
## Decision Support
### Quick Decision Guide
**Making a schema change?**
- Breaking change (drops/modifies data) → Multi-phase migration (expand-contract)
- Additive change (new columns/tables) → Single-phase migration
- Large table (millions of rows) → Use CONCURRENTLY for indexes
**Need zero downtime?**
- Schema change → Expand-contract pattern (5 phases)
- Data migration (< 10k rows) → Synchronous in-migration
- Data migration (> 1M rows) → Background worker pattern
**Planning rollback?**
- Added new schema only → Simple DOWN migration
- Modified/removed schema → Multi-phase rollback or fix forward
- Cannot lose data → Point-in-time recovery (PITR)
**Choosing migration tool?**
- Python/Django → Django Migrations
- Python/SQLAlchemy → Alembic
- Node.js/TypeScript → Prisma Migrate or Knex.js
- Enterprise/multi-language → Flyway or Liquibase
**→ See [references/decision-trees.md](./references/decision-trees.md) for comprehensive decision frameworks**
## Troubleshooting
### Common Issues Quick Reference
**Migration failed halfway** → Check database state, fix forward with repair migration
**Schema drift detected** → Use autogenerate to create reconciliation migration
**Cannot rollback (no downgrade)** → Create reverse migration or fix forward
**Foreign key violation** → Clean data before adding constraint, or add as NOT VALID
**Migration locks table too long** → Use CONCURRENTLY, add columns in phases, batch updates
**Circular dependency** → Create merge migration or reorder dependencies
**→ See [references/troubleshooting.md](./references/troubleshooting.md) for detailed solutions with examples**
## Navigation
### Detailed References
- **[🌳 Decision Trees](./references/decision-trees.md)** - Schema migration strategies, zero-downtime patterns, rollback strategies, migration tool selection, and data migration approaches. Load when planning migrations or choosing strategies.
- **[🔧 Troubleshooting](./references/troubleshooting.md)** - Failed migration recovery, schema drift detection, migration conflicts, rollback failures, data integrity issues, and performance problems. Load when debugging migration issues.
## Remember
- Test migrations on copy of production data
- Have rollback plan ready
- Monitor during deployment
- Communicate with team about schema changes
- Keep migrations small and focused
Related in General
modeling-omnistudio-epc-catalog
IncludedSalesforce Industries CME EPC product-modeling skill for Product2-based catalog creation. Use when creating EPC products, configuring product attributes, building offer bundles with Product Child Items, or reviewing EPC DataPack JSON metadata for product catalog changes. TRIGGER when: user creates or updates Product2 EPC records, AttributeAssignment payloads, AttributeMetadata/AttributeDefaultValues, Offer bundles, or ProductChildItem relationships. DO NOT TRIGGER when: designing OmniScripts/FlexCards/Integration Procedures (use building-omnistudio-omniscript, building-omnistudio-flexcard, or building-omnistudio-integration-procedure), implementing Apex business logic (use generating-apex), or troubleshooting deployment pipelines (use deploying-metadata).
relationship-science-coach
IncludedUse this skill for direct, practical adult relationship coaching: couples conflict, repair, trust, marriage, dating, flirting, attachment patterns, emotional connection, sex, desire differences, eroticism, kink negotiation, affection, love languages, breakups, and long-term passion. Draw on Gottman, EFT and Hold Me Tight, attachment science, modern sex research, Perel, Nagoski, Kerner, Schnarch, Love and Stosny, and flexible love-language tools. Be concrete and low-hedge. Redirect only for imminent danger, abuse, coercive control, minors, non-consent, self-harm, stalking, or medical/legal/psychiatric decisions.
building-sf-integrations
IncludedSalesforce integration architecture and runtime plumbing with 120-point scoring. Use this skill to set up Named Credentials, External Credentials, External Services, REST/SOAP callout patterns, Platform Events, and Change Data Capture. TRIGGER when: user sets up Named Credentials, External Services, REST/SOAP callouts, Platform Events, CDC, or touches .namedCredential-meta.xml files. DO NOT TRIGGER when: Connected App/OAuth config (use configuring-connected-apps), Apex-only logic (use generating-apex), or data import/export (use handling-sf-data).
venue-templates
IncludedAccess comprehensive LaTeX templates, formatting requirements, and submission guidelines for major scientific publication venues (Nature, Science, PLOS, IEEE, ACM), academic conferences (NeurIPS, ICML, CVPR, CHI), research posters, and grant proposals (NSF, NIH, DOE, DARPA). This skill should be used when preparing manuscripts for journal submission, conference papers, research posters, or grant proposals and need venue-specific formatting requirements and templates.
let-fate-decide
IncludedDraws the 12 Houses of the Zodiac Tarot spread to inject entropy into planning when prompts are vague, ambiguous, or casually delegated. Interprets the spread to guide next steps. Use when the user says 'let fate decide', 'YOLO', 'whatever', 'idk', or other nonchalant phrases, makes Yu-Gi-Oh references, or when you are about to arbitrarily pick between multiple reasonable approaches. Prefer over ask-questions-if-underspecified when the user's tone is casual or playful rather than precision-seeking.
net-ops
IncludedCross-platform network troubleshooting (Windows, macOS, Linux) via local or remote shell. Use for: DNS broken, can't resolve hostnames, nslookup/dig works but apps fail, NRPT, WFP, scutil, /etc/resolver, systemd-resolved, /etc/resolv.conf, NetworkManager, VPN DNS leak residue (ProtonVPN/Mullvad/WireGuard/AnyConnect), AV/firewall blocking DNS or DoH, Tailscale DNS interaction, intermittent connectivity, remote diagnostics over SSH.