Upgrade to v3
Comprehensive guide for upgrading to Prisma ORM v3
This guide helps you upgrade your project to Prisma ORM v3. Version 3 includes several important changes that may affect your application, so please review this guide carefully before proceeding.
Before you begin
- Backup your database before starting the upgrade process
- Review the release notes for a complete list of changes
- Test the upgrade in a development or staging environment first
Key changes
Referential Actions
Prisma ORM 3 introduces native support for referential actions, which changes how cascading deletes are handled:
- The safety net that previously prevented cascading deletes at runtime has been removed
- You now have more control over referential actions
- You should explicitly define referential actions in your schema
Before (Prisma 2.x):
model User {
id Int @id @default(autoincrement())
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
author User @relation(fields: [authorId], references: [id])
authorId Int
}After (Prisma 3.x):
model User {
id Int @id @default(autoincrement())
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
author User @relation(
fields: [authorId],
references: [id],
onDelete: Cascade, // Explicit action required
onUpdate: Cascade // Optional: define update behavior
)
authorId Int
}Action Required: Review all your relation fields and add appropriate onDelete and onUpdate actions.
Named Constraints and Indexes
Prisma ORM 3 changes how constraints and indexes are named:
- New naming convention for constraints and indexes
- Clear distinction between
map(database-level name) andname(Prisma Client API name) - Primary and foreign key names are now part of the schema for supporting databases
Option 1: Keep Existing Constraint Names
If you need to maintain existing constraint names (for compatibility with other tools or conventions):
- Run
prisma db pullto update your schema with existing constraint names - The schema will include
@mapattributes for non-default constraint names
Option 2: Use New Default Naming Convention
To use Prisma ORM's new default naming convention:
- Run
prisma migrate devto generate a migration updating constraint names - Apply the migration to all environments
Example of constraint naming in schema:
model User {
id Int @id(map: "Custom_Primary_Key") @default(autoincrement())
email String @unique(map: "Custom_Unique_Constraint")
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
author User @relation(fields: [authorId], references: [id], map: "Custom_Foreign_Key")
authorId Int
}$queryRaw Method Changes
The $queryRaw method now only supports template literals for security:
Before (Prisma 2.x):
// String syntax (no longer supported in v3)
const result = await prisma.$queryRaw('SELECT * FROM User WHERE id = 1');After (Prisma 3.x):
// Template literal syntax (recommended)
const userId = 1;
const result = await prisma.$queryRaw`SELECT * FROM User WHERE id = ${userId}`;
// Or use $queryRawUnsafe (use with caution)
const unsafeResult = await prisma.$queryRawUnsafe(
'SELECT * FROM User WHERE id = $1',
userId
);Action Required: Update all $queryRaw calls in your codebase to use template literals or switch to $queryRawUnsafe with proper parameterization.
JSON Null Handling
Prisma ORM 3 introduces more precise handling of null values in JSON fields:
{ equals: null }now checks for database NULL values- New types are available for different null representations:
Prisma.JsonNull: Represents a JSON null valuePrisma.DbNull: Represents a database NULL valuePrisma.AnyNull: Matches either JSON null or database NULL
Before (Prisma 2.x):
// Ambiguous behavior in v2
const result = await prisma.log.findMany({
where: {
meta: {
equals: null // Could mean either JSON null or database NULL
}
}
});After (Prisma 3.x):
import { Prisma } from '@prisma/client';
// Check for JSON null
const jsonNullResults = await prisma.log.findMany({
where: {
meta: {
equals: Prisma.JsonNull
}
}
});
// Check for database NULL
const dbNullResults = await prisma.log.findMany({
where: {
meta: {
equals: Prisma.DbNull
}
}
});
// Check for either
const anyNullResults = await prisma.log.findMany({
where: {
meta: {
equals: Prisma.AnyNull
}
}
});
// Creating with specific null types
await prisma.log.create({
data: {
meta: Prisma.JsonNull // or Prisma.DbNull
}
});Action Required: Update all JSON field operations that involve null values to use the appropriate null type.
Update packages
To upgrade to Prisma ORM 3 from an earlier version, you need to update both the prisma and @prisma/client packages:
npm install @prisma/client@3
npm install -D prisma@3
npx prisma generateFor yarn, use yarn up prisma@3 @prisma/client@3. For pnpm, use pnpm upgrade prisma@3 @prisma/client@3.
Before you upgrade, check each breaking change below to see how the upgrade might affect your application.
Upgrade steps
- Add Referential Actions: Update your schema to include explicit
onDeleteandonUpdateactions for all relations. - Handle Constraint Naming: Decide whether to keep existing constraint names or migrate to the new naming convention.
- Update JSON Fields: Modify any JSON field operations that involve null values to use the new null types.
4. Update Application Code
- Update Raw Queries: Convert all
$queryRawcalls to use template literals or switch to$queryRawUnsafe. - Test Thoroughly: Pay special attention to:
- Relations and cascading deletes
- JSON field operations
- Any raw SQL queries
- Custom constraints and indexes
5. Migration Strategy for Production
- Test in Development: Test the upgrade in a development or staging environment first.
- Create a Backup: Always create a backup of your production database before upgrading.
- Schedule Downtime: Plan for a maintenance window if needed.
- Deploy Updates: Update your application with the new Prisma ORM 3 packages.
- Monitor: Keep an eye on your application after the upgrade.
Troubleshooting
Common Issues
-
Missing Referential Actions
- Symptom: Unexpected behavior with cascading deletes
- Solution: Add explicit
onDeleteandonUpdateactions to your relations
-
JSON Null Handling
- Symptom: Type errors when filtering JSON fields
- Solution: Use
Prisma.JsonNull,Prisma.DbNull, orPrisma.AnyNull
-
Raw Query Errors
- Symptom: Errors with
$queryRaw - Solution: Convert to template literals or use
$queryRawUnsafe
- Symptom: Errors with