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:

npm install @prisma/client@3
npm install -D prisma@3
npx prisma generate

For 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

  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