database-migrations
Skill1 starsChanged 5 months agoMITView on GitHub
Modifies database schemas safely with migration strategies, rollback procedures, and zero-downtime deployments using Drizzle ORM.
We split this skill into the rules it gives an agent
4 rules. 0 are common, 4 are distinctive, and 0 are very specific to this project.
0
Common
Most of the 42 edited versions we read keep these.
4
Distinctive
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 11
Never modify production directly: - Always use migrations
- Distinctive: line 13
Plan for rollback: - Every migration should be reversible
- Distinctive: line 43
Safe: Add nullable column or with default
- Distinctive: line 171
If failed, restore to timestamp
“Common” is measured: kept by at least 6 in 10 of the 42 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Database Migrations
Safe schema modifications with rollback procedures.
Core Principles
- Never modify production directly - Always use migrations
- Test migrations on copy first - Catch issues early
- Plan for rollback - Every migration should be reversible
- Zero-downtime when possible - Expand-contract pattern
Drizzle ORM Workflow
Generate Migration
# After modifying schema.ts
bunx drizzle-kit generate:pg --name add_user_statusReview Generated SQL
cat drizzle/migrations/XXXX_add_user_status.sqlApply Migration
bunx drizzle-kit push:pg
# Or for production:
bunx drizzle-kit migrateSafe Migration Patterns
Adding a Column
Safe: Add nullable column or with default
// schema.ts
export const users = pgTable('users', {
id: serial('id').primaryKey(),
email: text('email').notNull(),
status: text('status').default('active'), // Safe: has default
});Dangerous: Adding NOT NULL without default
-- This will FAIL if table has data
ALTER TABLE users ADD COLUMN status TEXT NOT NULL;
-- Safe version:
ALTER TABLE users ADD COLUMN status TEXT;
UPDATE users SET status = 'active' WHERE status IS NULL;
ALTER TABLE users ALTER COLUMN status SET NOT NULL;Renaming a Column (Zero-Downtime)
Phase 1: Add new column
ALTER TABLE users ADD COLUMN new_name TEXT;
UPDATE users SET new_name = old_name;Phase 2: Code reads from both, writes to both
// During transition
user.displayName = user.new_name ?? user.old_name;
await db.update(users).set({
old_name: value,
new_name: value,
});Phase 3: Remove old column
ALTER TABLE users DROP COLUMN old_name;Adding Foreign Key
-- Add column without constraint first
ALTER TABLE posts ADD COLUMN author_id INTEGER;
-- Backfill data
UPDATE posts SET author_id = (SELECT id FROM users WHERE email = posts.author_email);
-- Then add constraint
ALTER TABLE posts ADD CONSTRAINT fk_author
FOREIGN KEY (author_id) REFERENCES users(id);
-- Finally remove old column
ALTER TABLE posts DROP COLUMN author_email;Rollback Procedures
With Drizzle
# Drizzle doesn't have built-in rollback
# Keep rollback SQL files manually
# drizzle/rollbacks/XXXX_add_user_status.sql
ALTER TABLE users DROP COLUMN status;Automated Rollback Script
import { sql } from 'drizzle-orm';
async function rollback(db: Database, migrationName: string) {
const rollbackPath = `drizzle/rollbacks/${migrationName}.sql`;
const rollbackSql = await Bun.file(rollbackPath).text();
await db.execute(sql.raw(rollbackSql));
console.log(`Rolled back: ${migrationName}`);
}Pre-Migration Checklist
- Backup database
- Review generated SQL
- Test on staging/copy
- Prepare rollback script
- Schedule during low-traffic
- Notify team
# Backup before migration
pg_dump $DATABASE_URL > backup_$(date +%Y%m%d_%H%M%S).sqlNeon Database Specifics
Branch for Testing
# Create test branch
neonctl branches create --name migration-test
# Get connection string
neonctl connection-string migration-test
# Test migration
DATABASE_URL=$TEST_URL bunx drizzle-kit push:pg
# If successful, apply to main
# If failed, delete branch
neonctl branches delete migration-testPoint-in-Time Recovery
Neon supports instant recovery. Before risky migrations:
- Note current timestamp
- Run migration
- If failed, restore to timestamp
Large Table Migrations
For tables with millions of rows:
Batch Updates
async function batchUpdate(
db: Database,
batchSize = 1000
) {
let updated = 0;
let lastId = 0;
while (true) {
const result = await db.execute(sql`
UPDATE users
SET status = 'active'
WHERE id > ${lastId}
AND status IS NULL
ORDER BY id
LIMIT ${batchSize}
RETURNING id
`);
if (result.rowCount === 0) break;
lastId = result.rows[result.rows.length - 1].id;
updated += result.rowCount;
console.log(`Updated ${updated} rows...`);
// Pause to reduce load
await new Promise(r => setTimeout(r, 100));
}
return updated;
}Migration Testing
import { describe, it, expect, beforeAll, afterAll } from 'bun:test';
describe('Migration: add_user_status', () => {
let testDb: Database;
beforeAll(async () => {
// Create test database
testDb = await createTestDatabase();
// Seed with test data
await seedTestData(testDb);
});
afterAll(async () => {
await testDb.close();
});
it('should add status column with default value', async () => {
await runMigration(testDb, 'add_user_status');
const users = await testDb.select().from(usersTable);
expect(users[0].status).toBe('active');
});
it('should be reversible', async () => {
await runMigration(testDb, 'add_user_status');
await runRollback(testDb, 'add_user_status');
const columns = await getTableColumns(testDb, 'users');
expect(columns).not.toContain('status');
});
});Other versions46 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 46
- loulanyue/awesome-claude-notes★ 272same name
- langchain-ai/skills-benchmarks★ 116same name
- Fmarzochi/EGC★ 61same name
- skateddu/claude-code-python-setup★ 28same name
- wpank/ai★ 11same name
- gongyijie85/dsh-ecc★ 8same name
- zero-click/zero-ratchet★ 8same name
- sponge-b0b/Polaris★ 4same name
- chadixearth/graphyloop★ 3same name
- kimtth/agent-skill-100-lines-or-less★ 2same name
36 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
Used alongsideProjects with it also use deployment-patterns, postgres-patterns and 10 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
royaluniondesign-sysSkilldeployment-patterns
Deployment workflows, CI/CD pipeline patterns, Docker containerization, health checks, rollback strategies, and production readiness checklists for web applications.
Also in 5 projects that use this
nek1987Skillpostgres-patterns
PostgreSQL patterns for reviewing migrations and writing efficient queries. Use when reviewing Alembic migrations, optimizing queries, or debugging database issues.
Also in 5 projects that use this
HABUBUSSSkillbackend-patterns
Backend architecture patterns, API design, database optimization, and server-side best practices for Node.js, Express, and Next.js API routes.
Also in 7 projects that use this
xenitV1Skillpython-patterns
Python development principles and decision-making. Framework selection, async patterns, type hints, project structure. Teaches thinking, not copying.
Also in 3 projects that use this
MicrosoftSkillapi-design
Guide for designing and documenting RESTful APIs. Use when asked to design an API, create endpoints, or document an API.
Also in 9 projects that use this
royaluniondesign-sysSkillsearch-first
Research-before-coding workflow. Search for existing tools, libraries, and patterns before writing custom code. Invokes the researcher agent.
Also in 3 projects that use this
In this repository54 other files it gives its agents.
- AGENTS.mdAGENTS.md
- skills/deep-recon/agents.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- adversarial-researchSkill
- algorithmic-artSkill
- api-integrationSkill
- breakdownSkill
- c4-architectSkill
- canvas-designSkill
- coding-agentsSkill
- compound-engineeringSkill
- context-budgetSkill
- counterfactualSkill
- critiqueSkill
- d3js-visualizationSkill
- data-analyst-agentSkill
- deep-reconSkill
- design-tasteSkill
- doc-coauthoringSkill
- e2b-sandboxSkill
- ecosystem-auditSkill
- excalidraw-diagramSkill
- executing-plansSkill
- frontend-designSkill
- fullstack-agentSkill
- grillSkill
- kickoffSkill
- mcp-builderSkill
- model-migrationSkill
- naming-the-machineSkill
- full-output-enforcementSkill
- package-researchSkill
- pdf-generationSkill
- pp2pSkill
- pp3pSkill
- prompt-engineerSkill
- prompt-groundingSkill
- redesignSkill
- requesting-code-reviewSkill
- reverse-engineer-to-learnSkill
- review-changesSkill
- scratchpadSkill
- shipSkill
- slack-gif-creatorSkill
- sprint-architectSkill
- techdebtSkill
- test-and-fixSkill
- threat-modelSkill
- verification-before-completionSkill
- visual-verdictSkill
- webapp-testingSkill
- web-asset-generatorSkill
- whatdidimissSkill
- writing-plansSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

