CHAPTER 3Models
Models are the equivalent of "entities" for Relational Databases or Document Databases. They are the types of things we want to store.
Declaring Models
The model comprises a sequence of model
entries which define the entities in your model. You can also define enum
types.
The naming convention for models is singular and PascalCase, so an entity representing a movie would be called Movie
:
model Movie {
// ...
}
Once the model is synchronized with the database, these names are preserved exactly, so they usually have to be written within double-quotes (especially in Postgres or SQLite3):
SELECT * FROM "Movie";
Field Definition
Each field has:
- A name.
- A type, with optional type modifiers.
- Optional attributes.
model Movie {
id Int @id @default(autoincrement())
title String
year Int
duration Int
forFamilies Boolean @default(false)
createdAt DateTime @default(now())
@@unique([title, year])
}
Scalar Types
Scalar types are: String
, Boolean
, Int
, BigInt
, Float
, Decimal
, DateTime
, Json
and Bytes
.
Type modifiers
You can append the following modifiers to any type:
?
a field is "optional" (it can benull
).[]
the field is then a list.
Attributes
Field attributes include:
@id | The field is a primary key |
@default(x) | The default value for the field is x |
@unique | The field must have a unique constraint |
@relation(...) | To describe how entites are related |
@map(name) | To use a different name in the database |
Entity attributes include:
@@id(f1, f2, ...) | A primary key with more than one field |
@@index(f1, f2, ...) | An index is needed on certain fields |
@@map(name) | Alternate name in the database |
@@unique(f1, f2, ...) | Unique constraint on field set |
IDs in MongoDB
Since MongoDB always introduces the _id
field as a primary key, in Prisma
the IDs have to be defined as follows if the underlying database is MongoDB:
model User {
id String @id @default(auto()) @map("_id") @db.ObjectId
// ...
}
Relationships
In relationships, the field's model type is another model. A relation involver, actually, two ways of working. From the perspective of the parent, a fields could include an array of all the children. From the perspective of the child, a field could contain all the data of the parent.
An example can illustrate this:
model Post {
postId Int @id @default(autoincrement())
comments Comment[]
}
model Comment {
commentId Int @id @default(uuid())
postId Int // <- special field for the hierarchical relationship
parentPost Post @relation(fields: [postId], references: [postId])
}
The following line in the Post
model
comments Comment[]
says that a Post
can have many comments (a hierarchical relationship). It could have zero, also.
On the child side, we have to be specific about what fields are involved:
postId Int // maybe there is no parent
parentPost Post @relation(fields: [postId], references: [id])
Generating relationships automatically with the Prisma VSCode extension
One nice thing about the Prisma VSCode extension is that you can automatically generate the relationship fields if you just declare one side of the relationship. By typing the line comments Comment[]
in the Post
(and having declared the Comment
model as well), then, upon reformatting the code, the fields for the comments appear automatically. It is good to check them and adapt any parts that you want to customize.
Many to many relationships
A many to many relationship would be implemented in the following way:
model User {
id String @id @default(uuid()) // generates a UUID
firstName String
lastName String
messages Message[]
}
model Chat {
id String @id @default(uuid())
title String
messages Message[]
}
model Message {
id String @id @default(uuid())
text String
authorId String
author User @relation(fields: [authorId], references: [id])
chatId String
chat Chat @relation(fields: [chatId], references: [id])
}
In this case, we have a "pivot table", Message
, which is a type of entity which sits below both User
and Chat
, since messages have that specific context, the author and the chat to which they belong. It is, as explained when modelling data, just the application of 2 hierarchical relationships that coincide inside an entity, in this case Message
.