This document provides comprehensive instructions for managing database migrations in the vatix-backend project using Prisma.
The vatix-backend uses Prisma as the database migration tool, which is already aligned with our PostgreSQL stack and provides type-safe database access.
- Node.js >= 18.0.0
- PostgreSQL database
- Environment variables configured (see
.env.example)
Create a .env file based on .env.example:
cp .env.example .envEnsure the following environment variables are set:
# Database connection
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/vatix"
# Redis (for production)
REDIS_URL="redis://localhost:6379"
# Node environment
NODE_ENV="development"To create a new migration after modifying prisma/schema.prisma:
# Generate migration file with descriptive name
npm run prisma:migrate -- --name add_new_feature
# Or using pnpm
pnpm prisma:migrate -- --name add_new_featureThis will:
- Compare schema changes with current database state
- Generate migration SQL in
prisma/migrations/ - Apply the migration to the database
- Generate updated Prisma Client
To apply migrations without creating new ones (production deployment):
npm run prisma:migrate deploy
# or
pnpm prisma:migrate deploynpm run prisma:migrate reset
# or
pnpm prisma:migrate resetAfter schema changes, regenerate the client:
npm run prisma:generate
# or
pnpm prisma:generateOpen Prisma Studio to inspect database content:
npm run prisma:studio
# or
pnpm prisma:studioMigration files are stored in prisma/migrations/ with timestamp prefixes:
prisma/migrations/
├── 20260122080015_init/
│ └── migration.sql
├── 20260123090000_add_new_feature/
│ └── migration.sql
└── migration_lock.toml
- Use descriptive, snake_case names
- Include timestamp automatically added by Prisma
- Example:
add_user_preferences,create_order_indexes
- Always review generated SQL before applying
- Test migrations on staging before production
- Use descriptive migration names
- Consider data preservation for destructive changes
- Make incremental changes - one logical change per migration
- Add indexes for performance improvements
- Use constraints for data integrity
- Document complex migrations in comments
- Backup database before major migrations
- Test migrations on staging environment
- Use
migrate deploy(notmigrate dev) in production - Monitor migration logs for errors
The CI pipeline includes migration checks:
# From .github/workflows/ci.yml
- name: Run migrations
run: pnpm prisma:migrate deploy
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/vatixTo check if migrations are in sync with schema:
# This will fail if schema and migrations don't match
npx prisma migrate diff --from-migrations prisma/migrations --to-schema-datamodel prisma/schema.prismamodel NewTable {
id String @id @default(uuid())
createdAt DateTime @default(now())
@@map("new_tables")
}model Market {
// ... existing fields
newField String?
}model Market {
// ... existing fields
@@index([status, endTime])
}- Create migration with type change
- Test data conversion
- Consider multi-step migration for complex changes
-
Migration lock stuck
rm prisma/migrations/migration_lock.toml
-
Database connection errors
- Check
DATABASE_URLformat - Verify PostgreSQL is running
- Check database exists
- Check
-
Schema drift
# Reset to match migration files npx prisma migrate reset
- Check Prisma Migration Docs
- Review generated SQL before applying
- Use
--preview-featureflags for advanced features
Prisma doesn't support automatic rollbacks. Manual rollback process:
-
Create rollback migration
npx prisma migrate dev --name rollback_feature_name
-
Manually write reverse SQL in the migration file
-
Test rollback thoroughly on staging
The project includes several helpful scripts in package.json:
{
"prisma:generate": "prisma generate",
"prisma:migrate": "prisma migrate dev",
"prisma:studio": "prisma studio",
"prisma:seed": "tsx prisma/seed.ts"
}To populate database with initial data:
npm run prisma:seed
# or
pnpm prisma:seedThis runs the seed script at prisma/seed.ts which can be customized for your needs.