Prisma Next is in early access.Read the docs
Upgrade Prisma ORM

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) and name (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):

  1. Run prisma db pull to update your schema with existing constraint names
  2. The schema will include @map attributes for non-default constraint names

Option 2: Use New Default Naming Convention

To use Prisma ORM's new default naming convention:

  1. Run prisma migrate dev to generate a migration updating constraint names
  2. 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 value
    • Prisma.DbNull: Represents a database NULL value
    • Prisma.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:

bun add @prisma/client@3
bun add --dev prisma@3
bunx prisma generate

Upgrade steps

  1. Add Referential Actions: Update your schema to include explicit onDelete and onUpdate actions for all relations.
  2. Handle Constraint Naming: Decide whether to keep existing constraint names or migrate to the new naming convention.
  3. Update JSON Fields: Modify any JSON field operations that involve null values to use the new null types.

4. Update Application Code

  1. Update Raw Queries: Convert all $queryRaw calls to use template literals or switch to $queryRawUnsafe.
  2. 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

  1. Test in Development: Test the upgrade in a development or staging environment first.
  2. Create a Backup: Always create a backup of your production database before upgrading.
  3. Schedule Downtime: Plan for a maintenance window if needed.
  4. Deploy Updates: Update your application with the new Prisma ORM 3 packages.
  5. Monitor: Keep an eye on your application after the upgrade.

Troubleshooting

Common Issues

  1. Missing Referential Actions

    • Symptom: Unexpected behavior with cascading deletes
    • Solution: Add explicit onDelete and onUpdate actions to your relations
  2. JSON Null Handling

    • Symptom: Type errors when filtering JSON fields
    • Solution: Use Prisma.JsonNull, Prisma.DbNull, or Prisma.AnyNull
  3. Raw Query Errors

    • Symptom: Errors with $queryRaw
    • Solution: Convert to template literals or use $queryRawUnsafe

Next Steps

On this page