Prisma Migrations — Version Control for Database Schema
In this tutorial, you will learn about Prisma Migrations. We cover key concepts, practical examples, and best practices to help you master this topic.
Prisma Migrations track database schema changes in version-controlled SQL files, allowing you to evolve your database schema alongside your application code with predictable, repeatable deployments.
What You'll Learn
By the end of this lesson you will create migrations with prisma migrate dev, apply migrations in production with prisma migrate deploy, handle Migration conflicts, roll back changes, and seed data.
Why It Matters
Database schema changes are risky. Without migrations, developers manually run SQL scripts in different environments, leading to inconsistency. Prisma Migrations make schema changes as predictable as code changes.
Real-World Use
DodaZIP runs prisma migrate deploy as part of the CI/CD pipeline. Every deployment first applies pending migrations, then starts the application. This ensures the database is always in sync with the code.
flowchart LR
A[Schema Change] -->|prisma migrate dev| B[Migration File]
B -->|Commit| C[Git Repository]
C -->|CI/CD| D[prisma migrate deploy]
D -->|Apply SQL| E[(Production DB)]
C -->|CI/CD| F[prisma migrate deploy]
F -->|Apply SQL| G[(Staging DB)]
style E fill:#2d3748,color:#fff
Creating Migrations
Generate migration files from schema changes.
# Development: Create and apply a migration
npx prisma migrate dev --name add_user_profile
# This:
# 1. Detects schema changes
# 2. Creates migration SQL file
# 3. Applies it to the database
# 4. Generates Prisma Client
# Create migration without applying
npx prisma migrate dev --create-only --name add_user_profile
# Reset database (drop all tables and re-run migrations)
npx prisma migrate reset
# Check migration status
npx prisma migrate status
# create_migration.py
# Migration creation workflow
def migration_workflow():
print("Migration Creation Workflow:")
print()
print("1. Edit schema.prisma (add/change models)")
print("2. Run: npx prisma migrate dev --name <description>")
print("3. Review the generated SQL file")
print("4. Commit migration files to git")
print()
print("Migration files created in:")
print(" prisma/migrations/<timestamp>_<name>/")
print(" migration.sql")
print(" migration_lock.toml")
print()
print("Best practices:")
print(" - Use descriptive migration names")
print(" - Review SQL before committing")
print(" - Never edit existing migrations")
migration_workflow()
Production Deployments
Apply migrations safely in production.
# Production deployment
npx prisma migrate deploy
# This:
# 1. Checks which migrations have been applied
# 2. Applies only pending migrations
# 3. Does NOT generate client (run separately)
# Generate client for production
npx prisma generate
# In package.json:
# "scripts": {
# "deploy": "prisma migrate deploy && prisma generate"
# }
# production_deploy.py
# Production migration deployment
def deployment_checklist():
print("Production Deployment Checklist:")
print()
print("Before deployment:")
print(" [ ] Backup the database")
print(" [ ] Test migrations on staging")
print(" [ ] Review migration SQL")
print(" [ ] Schedule maintenance window if needed")
print()
print("Deployment commands:")
print(" 1. npx prisma migrate deploy")
print(" 2. npx prisma generate")
print(" 3. Start application")
print()
print("After deployment:")
print(" [ ] Run health checks")
print(" [ ] Verify data integrity")
print(" [ ] Monitor error logs")
deployment_checklist()
Handling Conflicts
Resolve migration conflicts when working in a team.
# conflict_resolution.py
# Migration conflict scenarios
def handle_conflicts():
print("Migration Conflict Scenarios:")
print()
print("1. Team member created a migration you don't have")
print(" Solution: git pull, then migrate dev")
print()
print("2. Local migration diverged from remote")
print(" Solution: migrate reset, then migrate dev")
print()
print("3. Migration failed during apply")
print(" Solution: Fix the issue, then migrate dev again")
print()
print("4. Manual database changes conflict with migrations")
print(" Solution: prisma db pull to sync schema")
print()
print("General tips:")
print(" - Always pull latest migrations before creating new ones")
print(" - Use --create-only for complex migrations")
print(" - Keep migrations small and focused")
handle_conflicts()
Seeding Data
Populate the database with initial or test data.
// prisma/seed.ts
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
async function main() {
const user = await prisma.user.create({
data: {
email: 'admin@dodatech.com',
name: 'Admin',
posts: {
create: [
{ title: 'Welcome Post', content: 'Hello World!' },
{ title: 'Getting Started', content: 'Learn Prisma' },
]
}
}
});
console.log('Seed complete:', user.email);
}
main()
.catch(console.error)
.finally(() => prisma.$disconnect());
# Configure seed in package.json:
# "prisma": { "seed": "ts-node prisma/seed.ts" }
# Run seed
npx prisma db seed
Common Mistakes
Editing existing migration files: Never edit a migration that has been applied. Create a new migration to fix issues.
Running migrate dev in production: migrate dev is for development. Use migrate deploy for production deployments.
Not testing migrations: Always test migrations on a copy of production data before deployment.
Skipping prisma generate after migration: The client must be regenerated after every migration. Automate this in your build script.
Not committing migration files: Migration files must be committed to version control. Without them, production migrations fail.
Practice Questions
What is the difference between migrate dev and migrate deploy? migrate dev creates and applies migrations (development). migrate deploy applies existing migrations (production).
What happens when you run prisma migrate dev? It detects schema changes, creates a migration file, applies it to the database, and generates the client.
How do you reset the database? Run prisma migrate reset, which drops all tables and reapplies all migrations.
What is the purpose of prisma db seed? It runs the seed script to populate the database with initial data.
Challenge: Create a migration workflow for a team project including branching, merge Conflict Resolution, deployment pipeline, and rollback Strategy.
FAQ
Mini Project
Create a migration plan for adding a Comment model to an existing blog schema. Include the schema change, migration creation, seed data, and production deployment steps.
def migration_plan():
print("Migration Plan: Add Comment Model")
print()
print("1. Add model to schema.prisma:")
print(" model Comment {")
print(" id Int @id @default(autoincrement())")
print(" content String")
print(" postId Int")
print(" post Post @relation(fields: [postId], references: [id])")
print(" authorId Int")
print(" author User @relation(fields: [authorId], references: [id])")
print(" }")
print()
print("2. Create migration:")
print(" npx prisma migrate dev --name add_comments")
print()
print("3. Update seed.ts with comment data")
print("4. Deploy: prisma migrate deploy")
migration_plan()
What's Next
Next: Prisma Client for using the generated client.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro