A relation is a connection between two models in the Prisma schema. For example, there is a one-to-many relation between The following Prisma schema defines a one-to-many relation between the Relational databases MongoDB
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 // relation scalar field (used in the `@relation` attribute above) } At a Prisma level, the
At a Prisma level, a connection between two models is always represented by a relation field on each side of the relation. Relations in the databaseRelational databasesThe following entity relationship diagram defines the same one-to-many relation between the
In SQL, you use a foreign key to create a relation between two tables. Foreign keys are stored on one side of the relation. Our example is made up of:
In the Prisma schema, the foreign key / primary key relationship is represented by the
MongoDBFor MongoDB, Prisma currently uses a normalized data model design, which means that documents reference each other by ID in a similar way to relational databases. The following document represents a
The following list of
This data structure
represents a 1-n relation because multiple
|
Model | Field | Relational | Relation field |
---|---|---|---|
User
| id
| Int
| No |
email
| String
| No | |
role
| Role
| No | |
posts
| Post[]
| Yes (Prisma-level) | |
Post
| id
| Int
| No |
title
| String
| No | |
authorId
| Int
| No (relation scalar field) | |
author
| User
| Yes (annotated) |
Both posts
and author
are relation fields because their types are not scalar types but other models.
Also note that the annotated relation field author
needs to link the relation scalar field authorId
on the Post
model inside the @relation
attribute. The relation scalar represents the foreign key in the underlying database.
The other relation field called posts
is defined purely on a Prisma-level, it doesn't manifest in the
database.
Annotated relation fields and relation scalar fields
Relations that require one side of the relation to be annotated with the @relation
attribute are referred to as annotated relation fields. This includes:
- 1-1
- 1-n
- m-n for MongoDB only
The side of the relation which is annotated with the @relation
attribute represents the side that stores the foreign key in the underlying database. The "actual" field that represents the foreign key is required on that side of the relation as well, it's called relation scalar field, and is referenced inside @relation
attribute:
Relational databases
MongoDB
author User @relation(fields: [authorId], references: [id])
authorId Int
A scalar field becomes a relation scalar field when it's used in the fields
of a @relation
attribute.
Relation scalar fields are read-only in the generated Prisma Client API. If you want to update a relation in your code, you can do so using nested writes.
Relation scalar naming conventions
Because a relation scalar field always belongs to a relation field, the following naming convention is common:
- Relation field:
author
- Relation scalar field:
authorId
(relation field name +Id
)
The @relation attribute
The @relation
attribute can only be applied to the relation fields, not to scalar fields.
The
@relation
attribute is required when:
- you define a 1-1 or 1-n relation, it is required on one side of the relation (with the corresponding relation scalar field)
- you need to disambiguate a relation (that's e.g. the case when you have two relations between the same models)
- you define a self-relation
- you define an m-n for MongoDB
- you need to control how the relation table is represented in the underlying database (e.g. use a specific name for a relation table)
Note: Implicit m-n relations in relational databases do not require the
@relation
attribute.
Disambiguating relations
When you define two relations between two the same models, you need to add the name
argument in the @relation
attribute to disambiguate them. As an example for why that's needed, consider the following models:
Relational databases
MongoDB
model User {
id Int @id @default(autoincrement())
name String?
writtenPosts Post[]
pinnedPost Post?
}
model Post {
id Int @id @default(autoincrement())
title String?
author User @relation(fields: [authorId], references: [id])
authorId Int
pinnedBy User? @relation(fields: [pinnedById], references: [id])
pinnedById Int?
}
In that case, the relations are ambiguous, there are four different ways to interpret them:
User.writtenPosts
↔Post.author
+Post.authorId
User.writtenPosts
↔Post.pinnedBy
+Post.pinnedById
User.pinnedPost
↔Post.author
+Post.authorId
User.pinnedPost
↔Post.pinnedBy
+Post.pinnedById
To disambiguate these relations, you need to annotate the
relation fields with the @relation
attribute and provide the name
argument. You can set any name
(except for the empty string ""
), but it must be the same on both sides of the relation:
Relational databases
MongoDB
model User {
id Int @id @default(autoincrement())
name String?
writtenPosts Post[] @relation("WrittenPosts")
pinnedPost Post? @relation("PinnedPost")
}
model Post {
id Int @id @default(autoincrement())
title String?
author User @relation("WrittenPosts", fields: [authorId], references: [id])
authorId Int
pinnedBy User? @relation(name: "PinnedPost", fields: [pinnedById], references: [id])
pinnedById Int?
}