Named constraints upgrade path

After upgrading to Prisma 3, the default naming convention for constraint and index names will change and your primary and foreign key names will now be part of the schema for databases that support them. Therefore the meaning of your existing Prisma schema will change.

Before you continue to evolve your schema and your database, you should decide which names for constraints and indexes you want to use on your project going forward.

You can either keep the names as they exist in your database or you can switch to use the names generated by Prisma, which follow the new naming convention.

This page describes the manual upgrade steps that you need to perform after upgrading to Prisma 3. You can pick either of the two options:

Option 1: I want to maintain my existing constraint and index names

If you want to keep your database unchanged and keep the existing names for constraints and indexes you need to pull them into your schema so Prisma is aware of them.

Reasons to keep your existing names might be:

  • Naming conventions you have to follow
  • Other tooling relying on the names
  • Personal preference

To keep existing names, run prisma db pull against the target environment. This will result in all names that do not match Prisma's naming convention for constraint and index names being pulled into your schema as map arguments on their respective attributes.

  1. Example schema:

    model User {
    id Int @id @default(autoincrement())
    name String @unique
    posts Post[]
    }
    model Post {
    id Int @id @default(autoincrement())
    title String
    authorName String @default("Anonymous")
    author User? @relation(fields: [authorName], references: [name])
    }
  2. Introspect your development database to populate the Prisma schema with constraint and index names in your underlying database that do not match Prisma's naming convention:

    $npx prisma db pull

    In this example, the highlighted constraints did not conform to Prisma's default naming convention and now include the map attribute field:

    model User {
    id Int @id(map: "Custom_Constraint_Name") @default(autoincrement())
    name String @unique
    posts Post[]
    }
    model Post {
    id Int @id @default(autoincrement())
    title String
    authorName String @default("Anonymous")
    author User? @relation(fields: [authorName], references: [name], map: "Custom_Foreign_Key_Constraint")
    }

Option 2: I want to use Prisma's default constraint and index names

If you want to keep your Prisma Schema clean and if you have no reasons preventing you from renaming constraints and indexes in your database, then you can create a migration to update the names.

Run prisma migrate dev to create a migration updating the constraint names to Prisma's defaults.

Afterwards, do not forget to prisma migrate deploy against your production environment if you have one to also update the names there. The schema below has no explicit constraint or index names spelled out, so Prisma will infer them.

  1. Example schema:
model User {
name String @id //inferred as User_pkey
posts Post[]
}
model Post {
id Int @id @default(autoincrement()) //inferred as Post_pkey
authorName String @default("Anonymous")
author User? @relation(fields: [authorName], references: [name]) //inferred as Post_authorName_fkey
}
  1. Run the prisma migrate dev command to generate a new migration:

    $npx prisma migrate dev

    This migration renames any constraints that do not currently follow Prisma's naming convention.

  2. Run the prisma migrate deploy command to apply the migration to your production environment:

    $npx prisma migrate deploy

Dealing with cases where more than one database environment is used for the same application

Checking whether your environments use identical names

Since Prisma did not offer a way to define constraint or index names explicitly in the past, you can face situations where your different database environments have differing constraint or index names.

In order to detect this:

  • Create a backup of your current prisma.schema file.
  • Run prisma db pull against each database environment, by saving the results to their own separate files using the --schema option. See reference

Then you can either manually inspect both files or use a diff tool in your IDE or in the terminal. If you see differences in constraint names, your production and local environments are out of sync and should be aligned.

In the following example, the Post model has a foreign key constraint with a custom name in production that does not match development.

Development environment:

model Post {
id Int @id @default(autoincrement())
title String
authorName String @default("Anonymous")
author User? @relation(fields: [authorName], references: [name], map: "Custom_Foreign_Key_Constraint")
}

Production environment:

model Post {
id Int @id @default(autoincrement())
title String
authorName String @default("Anonymous")
author User? @relation(fields: [authorName], references: [name], map: "Custom_Production_Name")
}

Aligning your environments if their constraint or index names differ

If the names in your environments differ, the safest option is to align your development environment with the names in your production environment. This makes sure that no changes need to be performed on your production database.

In order to achieve this:

  • Run prisma db pull against your production environment to pull in the constraint and index names
  • Switch to development and run prisma migrate dev to create a new migration. You can call that migration migration-to-sync-names
  • Switch to production, and run prisma migrate resolve --applied migration-to-sync-names to mark the migration as applied on production

Your migration history now contains a migration to ensure that the names of any new environments you spin up contain the same names as your production database. And Prisma knows not to apply this migration to production since you already marked it as applied.

Your environments are now in sync and you can proceed to the upgrade paths for migrate users. These let you choose your future naming scheme.

Edit this page on GitHub