Named constraints upgrade path
After upgrading to Prisma ORM 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 ORM, which follow the new naming convention.
This page describes the manual upgrade steps that you need to perform after upgrading to Prisma ORM 3. You can pick either of the two options:
- Option 1: I want to maintain my existing constraint and index names
- Option 2: I want to use Prisma ORM's default constraint and index names
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 ORM 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 ORM's naming convention for constraint and index names being pulled into your schema as map
arguments on their respective attributes.
-
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])
} -
Introspect your development database to populate the Prisma schema with constraint and index names in your underlying database that do not match Prisma ORM's naming convention:
npx prisma db pull
In this example, the highlighted constraints did not conform to Prisma ORM'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 ORM'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 ORM'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 ORM will infer them.
-
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
} -
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 ORM's naming convention.
-
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 ORM 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
schema.prisma
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 migrationmigration-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 ORM 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.