在 prisma 中我們非常仰賴 schema 去定義我們的 model ,那今天我們就來好好認識一下他~
prisma 得 models 有以下的功能:
PostgreSQL,或是對應的 collections (MongoDB)到你的 DB
prisma client 的基礎架構。typescript type definitions 的來源,確保整個 application 的 type safe。那今天會以下方的 schema 當作本次的範例
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
role Role @default(USER)
posts Post[]
profile Profile?
}
model Profile {
id Int @id @default(autoincrement())
bio String
user User @relation(fields: [userId], references: [id])
userId Int @unique
}
model Post {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
title String
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId Int
categories Category[]
}
model Category {
id Int @id @default(autoincrement())
name String
posts Post[]
}
enum Role {
USER
ADMIN
}
之後我們跑 migration 同步到我們的 DB
>npx prisma migrate dev
這邊有一個有趣的內容是,每當我們 migration 時候 prisma 會告訴我們是否需要 clean data 好讓 prisma 可以 migration ,這邊會確保 shcmea 的ㄧ至性是否與 data 符合,但你可能會想失去的資料怎麼辦,這邊筆者會在之後得內容分享給大家~
We need to reset the "test" schema at "sfo1.clusters.zeabur.com:31437"
Do you want to continue? All data will be lost. › (y/N)
打好 migration 名稱後就完成了~
✔ Enter a name for the new migration: … test
Applying migration `20240918153431_test`
The following migration(s) have been created and applied from new schema changes:
migrations/
└─ 20240918153431_test/
└─ migration.sql
Your database is now in sync with your schema.
✔ Generated Prisma Client (v5.19.1) to ./node_modules/@prisma/client in 93ms
prisma 有針對 schema 的 model name 有一套 Naming conventions 如下:
模型名稱必須符合 [A-Za-z][A-Za-z0-9_]* 的正則表達式。
這意味著模型名稱必須以字母開頭,後面可以接任意數量的字母、數字或下劃線。
模型名稱應該使用帕斯卡命名法(PascalCase)。
例如:User、Product、Order 等。
模型名稱應該使用單數形式。
不要使用複數形式,如 users 或 products。
也不要使用大寫形式,如 USERS。
Prisma 有許多內部使用的保留字不能作為模型名稱。
保留字
但當然如果你不想遵守 prisma 的 Naming conventions 的話,prisma 有提供一個 attribute @@map 讓你直接自動 mapping 到 DB 的 table
model Comment {
// Fields
@@map("comments")
}
在 prisma 中有一些 attribute 去對應 scalar filed 大家可以在使用時查表看看~ 完整的 scalar field types
例如 String 可以對應到 text、 varchar、TEXT 等等的 scalar type 根據不同的 DB 。
| Connector | Default mapping |
|---|---|
| PostgreSQL | text |
| SQL Server | nvarchar(1000) |
| MySQL | varchar(191) |
| MongoDB | String |
| SQLite | TEXT |
| CockroachDB | STRING |
model Comment {
id Int @id @default(autoincrement())
title String
content String
}
或者你要用直接使用原生的 scalar types 也是 OK
model Post {
id Int @id
title String @db.VarChar(200)
content String
}
如果要表達關聯關係可以透過 [] 並在對應的 table 用 @relation 描述關聯的對應欄位。
以及 ? 代表著這個欄位是 optional
model Post {
id Int @id @default(autoincrement())
// Other fields
comments Comment[] // A post can have many comments
}
model Comment {
id Int
// Other fields
post Post? @relation(fields: [postId], references: [id]) // A comment can have one post
postId Int?
}
如果是多對多則使用 [] 就可以
model Post {
id Int @id @default(autoincrement())
// Other fields
comments Comment[] // A list of comments
keywords String[] // A scalar list
}
有時候我們需要描述 fileds 中他是 table 的 id 欄位,或是有沒有 default value 等等,這些我們都需要額外定一下 attributes
ID 對 table 來說一個 unique 的欄位,對應著不同的 record ,用法如下
model User {
id Int @id @default(autoincrement())
name String?
}
補充一下如果再 relational databases 中如果你的 schema 沒有定 id 要記得提供一個 @unique 的 fields
@id 除了訂在單一一個欄位,也可以結合多個欄位的組合當作 id
model User {
firstName String
lastName String
email String @unique
isAdmin Boolean @default(false)
@@id([firstName, lastName])
}
預設情況下的個 model 的 id 將會叫做 firstName_lastName ,如果想要客製化 id name ,可以直接改在 @@id 中。
model User {
firstName String
lastName String
email String @unique
isAdmin Boolean @default(false)
@@id(name: "fullName", fields: [firstName, lastName])
}
同樣的你也可以指定某一個 fields 的 default value 是什麼,例如指定 createdAt 時間,或者是 published 這種 boolean 欄位等等
model Post {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
title String
published Boolean @default(false)
data Json @default("{ \"hello\": \"world\" }")
author User @relation(fields: [authorId], references: [id])
authorId Int
categories Category[] @relation(references: [id])
}
補充一個在 prisma 中 default 可以接受以下的值。
string 、boolean、int 等等[5, 6, 8] (Int[]) or ["Hello", "Goodbye"] (String[])。now() 指定當前時間,uuid() 自動產生 id 等等。double-quotes 去塞你的 json data ,@default("[]") ,或是你想使用 json object 記得加上反斜線 @default("{ \"hello\": \"world\" }").
和 ts 一樣我們可以定義 enum 當作 fileds 的 type
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
role Role @default(USER)
}
enum Role {
USER
ADMIN
}
✅ 前端社群 :
https://lihi3.cc/kBe0Y