Overview

The Prisma Client API is generated based on the models in your Prisma schema. Models are typically 1:1 mappings of your database tables.

In some cases, especially when using introspection, it might be useful to decouple the naming of database tables and columns from the names that are used in your Prisma Client API. This can be done via the @map and @@map attributes in your Prisma schema.

Example

Assume you have a database schema looking similar to this:

1CREATE TABLE users (
2 user_id SERIAL PRIMARY KEY NOT NULL,
3 name VARCHAR(256),
4 email VARCHAR(256) UNIQUE NOT NULL
5);
6CREATE TABLE posts (
7 post_id SERIAL PRIMARY KEY NOT NULL,
8 created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
9 title VARCHAR(256) NOT NULL,
10 content TEXT,
11 author_id INTEGER REFERENCES users(user_id)
12);
13CREATE TABLE profiles (
14 profile_id SERIAL PRIMARY KEY NOT NULL,
15 bio TEXT,
16 user_id INTEGER NOT NULL UNIQUE REFERENCES users(user_id)
17);
18CREATE TABLE categories (
19 category_id SERIAL PRIMARY KEY NOT NULL,
20 name VARCHAR(256)
21);
22CREATE TABLE post_in_categories (
23 post_id INTEGER NOT NULL REFERENCES posts(post_id),
24 category_id INTEGER NOT NULL REFERENCES categories(category_id)
25);
26CREATE UNIQUE INDEX post_id_category_id_unique ON post_in_categories(post_id int4_ops,category_id int4_ops);

When introspecting a database with that schema, you'll get a Prisma schema looking similar to this:

1model categories {
2 category_id Int @default(autoincrement()) @id
3 name String?
4 post_in_categories post_in_categories[]
5}
6
7model post_in_categories {
8 category_id Int
9 post_id Int
10 categories categories @relation(fields: [category_id], references: [category_id])
11 posts posts @relation(fields: [post_id], references: [post_id])
12
13 @@unique([post_id, category_id], name: "post_id_category_id_unique")
14}
15
16model posts {
17 author_id Int?
18 content String?
19 created_at DateTime? @default(now())
20 post_id Int @default(autoincrement()) @id
21 title String
22 users users? @relation(fields: [author_id], references: [user_id])
23 post_in_categories post_in_categories[]
24}
25
26model profiles {
27 bio String?
28 profile_id Int @default(autoincrement()) @id
29 user_id Int @unique
30 users users @relation(fields: [user_id], references: [user_id])
31}
32
33model users {
34 email String @unique
35 name String?
36 user_id Int @default(autoincrement()) @id
37 posts posts[]
38 profiles profiles?
39}

The are a few "issues" with this Prisma schema when the Prisma Client API is generated:

Adhering to Prisma's naming conventions

Prisma has a naming convention of camelCasing and using the singular form for Prisma models. If these naming conventions are not met, the Prisma schema can become harder to interpret and the generated Prisma Client API will feel less natural. Consider the following, generated model:

1model users {
2 user_id Int @default(autoincrement()) @id
3 posts posts[]
4 profiles profiles?
5}

Although profiles refers to a 1:1 relation, its type is currently called profiles in plural, suggesting that there might be many profiles in this relation. With Prisma conventions, the models and fields were ideally named as follows:

1model User {
2 user_id Int @default(autoincrement()) @id
3 posts Post[]
4 profile Profile?
5}

Because these fields are "Prisma-level" relation fields that do not manifest you can manually rename them in your Prisma schema.

Naming of annotated relation fields

Foreign keys are represented as a combination of a annotated relation fields and its corresponding relation scalar field in the Prisma schema. Here's how all the relations from the SQL schema are currently represented:

1model categories {
2 category_id Int @default(autoincrement()) @id
3 post_in_categories post_in_categories[] // virtual relation field
4}
5
6model post_in_categories {
7 category_id Int // relation scalar field
8 post_id Int // relation scalar field
9 categories categories @relation(fields: [category_id], references: [category_id]) // virtual relation field
10 posts posts @relation(fields: [post_id], references: [post_id])
11
12 @@unique([post_id, category_id], name: "post_id_category_id_unique")
13}
14
15model posts {
16 author_id Int?
17 post_id Int @default(autoincrement()) @id
18 users users? @relation(fields: [author_id], references: [user_id])
19 post_in_categories post_in_categories[]
20}
21
22model profiles {
23 profile_id Int @default(autoincrement()) @id
24 user_id Int @unique
25 users users @relation(fields: [user_id], references: [user_id])
26}
27
28model users {
29 user_id Int @default(autoincrement()) @id
30 posts posts[]
31 profiles profiles?
32}

Using @map and @@map to rename fields and models in the Prisma Client API

You can "rename" fields and models that are used in the Prisma Client by mapping them to the "original" names in the database using the @map and @@map attributes. For the example above, you could e.g. annotate your models as follows to prevent the mentioned issues.

After you introspected your database with prisma introspect, you can manually adjust the resulting Prisma schema as follows:

1model Category {
2 category_id Int @default(autoincrement()) @id
3 post_in_categories post_in_categories[]
4
5 @@map(name: "categories")
6}
7
8model PostInCategories {
9 category Category @map(name: "category_id")
10 post Post @map(name: "post_id")
11
12 @@unique([post, category], name: "post_id_category_id_unique")
13 @@map(name: "post_in_categories")
14}
15
16model Post {
17 post_id Int @default(autoincrement()) @id
18 author User? @map(name: "author_id")
19 post_in_categories PostInCategories[]
20
21 @@map(name: "posts")
22}
23
24model Profile {
25 profile_id Int @default(autoincrement()) @id
26 user_id User @map(name: "user_id")
27
28 @@map(name: "profiles")
29}
30
31model User {
32 user_id Int @default(autoincrement()) @id
33 posts Post[]
34 profiles Profile?
35
36 @@map(name: "users")
37}

With these changes, you're now adhering to Prisma's naming conventions and the generated Prisma Client API feels more "natural":

1// Nested writess
2const profile = await prisma.profile.create({
3 data: {
4 bio: 'Hello World',
5 user: {
6 create: {
7 name: 'Alice',
8 email: 'alice@prisma.io',
9 },
10 },
11 },
12})
13
14// Fluent API
15const userByProfile = await prisma.profile
16 .findOne({
17 where: { id: 1 },
18 })
19 .user()

Warning: @map and @@map attributes are removed when you run prisma introspect again. You therefore might want to back up your Prisma schema with these attributes in order to not having to annotate everything from scratch again after a re-introspection.

Renaming relation fields

Prisma-level relation fields (sometimes referred to as "virtual relation fields") only exist in the Prisma schema, but do not actually manifest in the underlying database. You can therefore name these fields whatever you want.

Consider the following example of an ambiguous relation in a SQL database:

1CREATE TABLE "User" (
2 id SERIAL PRIMARY KEY
3);
4CREATE TABLE "Post" (
5 id SERIAL PRIMARY KEY,
6 "author" integer NOT NULL,
7 "favoritedBy" INTEGER,
8 FOREIGN KEY ("author") REFERENCES "User"(id),
9 FOREIGN KEY ("favoritedBy") REFERENCES "User"(id)
10);

Prism's introspection will output the following Prisma schema:

1model Post {
2 id Int @default(autoincrement()) @id
3 author User @relation("Post_authorToUser", references: [id])
4 favoritedBy User? @relation("Post_favoritedByToUser", references: [id])
5}
6
7model User {
8 id Int @default(autoincrement()) @id
9 Post_Post_authorToUser Post[] @relation("Post_authorToUser")
10 Post_Post_favoritedByToUser Post[] @relation("Post_favoritedByToUser")
11}

Since the names of the virtual relation fields Post_Post_authorToUser and Post_Post_favoritedByToUser are based on the generated relation names, they don't look very friendly in the Prisma Client API. In that case, you can rename the relation fields to anything you like, e.g.:

1model Post {
2 id Int @default(autoincrement()) @id
3 author User @relation("Post_authorToUser", references: [id])
4 favoritedBy User? @relation("Post_favoritedByToUser", references: [id])
5}
6
7model User {
8 id Int @default(autoincrement()) @id
9 writtenPost Post[] @relation("Post_authorToUser")
10 favoritedPosts Post[] @relation("Post_favoritedByToUser")
11}

Warning: Prisma-level relation fields that were renamed in the Prisma schema will be reset when you run prisma introspect again. You therefore might want to back up your Prisma schema with these attributes in order to not having to annotate everything from scratch again after a re-introspection.

Edit this page on Github