Database mapping
The Prisma schema includes mechanisms that allow you to define names of certain database objects. You can:
- Map model and field names to different collection/table and field/column names
- Define constraint and index names
Mapping collection/table and field/column names
Sometimes the names used to describe entities in your database might not match the names you would prefer in your generated API. Mapping names in the Prisma schema allows you to influence the naming in your Client API without having to change the underlying database names.
A common approach for naming tables/collections in databases for example is to use plural form and snake_case notation. However, we recommended a different naming convention (singular form, PascalCase).
@map
and @@map
allow you to tune the shape of your Prisma Client API by decoupling model and field names from table and column names in the underlying database.
Map collection / table names
As an example, when you introspect a database with a table named comments
, the resulting Prisma model will look like this:
model comments {
// Fields
}
However, you can still choose Comment
as the name of the model (e.g. to follow the naming convention) without renaming the underlying comments
table in the database by using the @@map
attribute:
model Comment {
// Fields
@@map("comments")
}
With this modified model definition, Prisma Client automatically maps the Comment
model to the comments
table in the underlying database.
Map field / column names
You can also @map
a column/field name:
model Comment {
content String @map("comment_text")
email String @map("commenter_email")
type Enum @map("comment_type")
@@map("comments")
}
This way the comment_text
column is not available under prisma.comment.comment_text
in the Prisma Client API, but can be accessed via prisma.comment.content
.
Map enum names and values
You can also @map
an enum value, or @@map
an enum:
enum Type {
Blog,
Twitter @map("comment_twitter")
@@map("comment_source_enum")
}
Constraint and index names
You can optionally use the map
argument to explicitly define the underlying constraint and index names in the Prisma schema for the attributes @id
, @@id
, @unique
, @@unique
, @@index
and @relation
. (This is available in Prisma ORM version 2.29.0 and later.)
When introspecting a database, the map
argument will only be rendered in the schema if the name differs from Prisma ORM's default constraint naming convention for indexes and constraints.
If you use Prisma Migrate in a version earlier than 2.29.0 and want to maintain your existing constraint and index names after upgrading to a newer version, do not immediately run prisma migrate
or prisma db push
. This will change any underlying constraint name that does not follow Prisma ORM's convention. Follow the upgrade path that allows you to maintain existing constraint and index names.
Use cases for named constraints
Some use cases for explicitly named constraints include:
- Company policy
- Conventions of other tools
Prisma ORM's default naming conventions for indexes and constraints
Prisma ORM naming convention was chosen to align with PostgreSQL since it is deterministic. It also helps to maximize the amount of times where names do not need to be rendered because many databases out there they already align with the convention.
Prisma ORM always uses the database names of entities when generating the default index and constraint names. If a model is remapped to a different name in the data model via @@map
or @map
, the default name generation will still take the name of the table in the database as input. The same is true for fields and columns.
Entity | Convention | Example |
---|---|---|
Primary Key | {tablename}_pkey | User_pkey |
Unique Constraint | {tablename}_{column_names}_key | User_firstName_last_Name_key |
Non-Unique Index | {tablename}_{column_names}_idx | User_age_idx |
Foreign Key | {tablename}_{column_names}_fkey | User_childName_fkey |
Since most databases have a length limit for entity names, the names will be trimmed if necessary to not violate the database limits. We will shorten the part before the _suffix
as necessary so that the full name is at most the maximum length permitted.
Using default constraint names
When no explicit names are provided via map
arguments Prisma ORM will generate index and constraint names following the default naming convention.
If you introspect a database the names for indexes and constraints will be added to your schema unless they follow Prisma ORM's naming convention. If they do, the names are not rendered to keep the schema more readable. When you migrate such a schema Prisma will infer the default names and persist them in the database.
Example
The following schema defines three constraints (@id
, @unique
, and @relation
) and one index (@@index
):
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])
@@index([title, authorName])
}
Since no explicit names are provided via map
arguments Prisma will assume they follow our default naming convention.
The following table lists the name of each constraint and index in the underlying database:
Constraint or index | Follows convention | Underlying constraint or index names |
---|---|---|
@id (on User > id field) | Yes | User_pk |
@@index (on Post ) | Yes | Post_title_authorName_idx |
@id (on Post > id field) | Yes | Post_pk |
@relation (on Post > author ) | Yes | Post_authorName_fkey |
Using custom constraint / index names
You can use the map
argument to define custom constraint and index names in the underlying database.
Example
The following example adds custom names to one @id
and the @@index
:
model User {
id Int @id(map: "Custom_Primary_Key_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])
@@index([title, authorName], map: "My_Custom_Index_Name")
}
The following table lists the name of each constraint and index in the underlying database:
Constraint or index | Follows convention | Underlying constraint or index names |
---|---|---|
@id (on User > id field) | No | Custom_Primary_Key_Constraint_Name |
@@index (on Post ) | No | My_Custom_Index_Name |
@id (on Post > id field) | Yes | Post_pk |
@relation (on Post > author ) | Yes | Post_authorName_fkey |
Related: Naming indexes and primary keys for Prisma Client
Additionally to map
, the @@id
and @@unique
attributes take an optional name
argument that allows you to customize your Prisma Client API.
On a model like:
model User {
firstName String
lastName String
@@id([firstName, lastName])
}
the default API for selecting on that primary key uses a generated combination of the fields:
const user = await prisma.user.findUnique({
where: {
firstName_lastName: {
firstName: 'Paul',
lastName: 'Panther',
},
},
})
Specifying @@id([firstName, lastName], name: "fullName")
will change the Prisma Client API to this instead:
const user = await prisma.user.findUnique({
where: {
fullName: {
firstName: 'Paul',
lastName: 'Panther',
},
},
})