在 JavaScript 專案中對 PostgreSQL 進行內省
使用 Prisma ORM 內省你的資料庫
為了本指南的目的,我們將使用一個包含三個表的演示 SQL schema
CREATE TABLE "public"."User" (
id SERIAL PRIMARY KEY NOT NULL,
name VARCHAR(255),
email VARCHAR(255) UNIQUE NOT NULL
);
CREATE TABLE "public"."Post" (
id SERIAL PRIMARY KEY NOT NULL,
title VARCHAR(255) NOT NULL,
"createdAt" TIMESTAMP NOT NULL DEFAULT now(),
content TEXT,
published BOOLEAN NOT NULL DEFAULT false,
"authorId" INTEGER NOT NULL,
FOREIGN KEY ("authorId") REFERENCES "public"."User"(id)
);
CREATE TABLE "public"."Profile" (
id SERIAL PRIMARY KEY NOT NULL,
bio TEXT,
"userId" INTEGER UNIQUE NOT NULL,
FOREIGN KEY ("userId") REFERENCES "public"."User"(id)
);
注意:某些欄位用雙引號括起來,以確保 PostgreSQL 使用正確的字母大小寫。如果未使用雙引號,PostgreSQL 將把所有內容都讀取為小寫字元。
展開查看錶的圖形概覽
使用者
| 列名 | 型別 | 主鍵 | 外部索引鍵 | 必需 | 預設值 |
|---|---|---|---|---|---|
id | SERIAL | ✔️ | 否 | ✔️ | 自動遞增 |
name | VARCHAR(255) | 否 | 否 | 否 | - |
email | VARCHAR(255) | 否 | 否 | ✔️ | - |
帖子
| 列名 | 型別 | 主鍵 | 外部索引鍵 | 必需 | 預設值 |
|---|---|---|---|---|---|
id | SERIAL | ✔️ | 否 | ✔️ | 自動遞增 |
createdAt | TIMESTAMP | 否 | 否 | ✔️ | now() |
title | VARCHAR(255) | 否 | 否 | ✔️ | - |
content | TEXT | 否 | 否 | 否 | - |
published | BOOLEAN | 否 | 否 | ✔️ | false |
authorId | INTEGER | 否 | ✔️ | ✔️ | - |
個人資料
| 列名 | 型別 | 主鍵 | 外部索引鍵 | 必需 | 預設值 |
|---|---|---|---|---|---|
id | SERIAL | ✔️ | 否 | ✔️ | 自動遞增 |
bio | TEXT | 否 | 否 | 否 | - |
userId | INTEGER | 否 | ✔️ | ✔️ | - |
下一步,你將內省你的資料庫。內省的結果將是 Prisma schema 中的一個資料模型。
執行以下命令來內省你的資料庫
npx prisma db pull
此命令讀取在.env中定義的DATABASE_URL環境變數並連線到你的資料庫。連線建立後,它會內省資料庫(即讀取資料庫 schema)。然後,它將資料庫 schema 從 SQL 轉換為你的 Prisma schema 中的資料模型。
內省完成後,你的 Prisma schema 將被更新

資料模型現在看起來類似於這樣(請注意,模型的欄位為了更好的可讀性已被重新排序)
model Post {
id Int @id @default(autoincrement())
title String @db.VarChar(255)
createdAt DateTime @default(now()) @db.Timestamp(6)
content String?
published Boolean @default(false)
authorId Int
User User @relation(fields: [authorId], references: [id], onDelete: NoAction, onUpdate: NoAction)
}
model Profile {
id Int @id @default(autoincrement())
bio String?
userId Int @unique
User User @relation(fields: [userId], references: [id], onDelete: NoAction, onUpdate: NoAction)
}
model User {
id Int @id @default(autoincrement())
name String? @db.VarChar(255)
email String @unique @db.VarChar(255)
Post Post[]
Profile Profile?
}
Prisma ORM 的資料模型是你資料庫 schema 的宣告性表示,它作為生成的 Prisma Client 庫的基礎。你的 Prisma Client 例項將暴露針對這些模型量身定製的查詢。
目前,資料模型存在一些小“問題”
User關係欄位採用大寫,因此不符合 Prisma 的命名約定。為了表達更多的“語義”,如果此欄位名為author以更好地描述User和Post之間的關係,那將更好。User上的Post和Profile關係欄位以及Profile上的User關係欄位都採用大寫。為了符合 Prisma 的命名約定,這兩個欄位都應該小寫為post、profile和user。- 即使小寫後,
User上的post欄位仍然有些命名不當。那是因為它實際上指的是一個帖子列表——因此更好的名稱應該是複數形式:posts。
這些更改與生成的 Prisma Client API 相關,在其中使用小寫關係欄位author、posts、profile和user會更自然,更符合 JavaScript/TypeScript 開發者的習慣。因此,你可以配置你的 Prisma Client API。
因為關係欄位是虛擬的(即它們不直接在資料庫中體現),你可以在你的 Prisma schema 中手動重新命名它們而無需更改資料庫
model Post {
id Int @id @default(autoincrement())
title String @db.VarChar(255)
createdAt DateTime @default(now()) @db.Timestamp(6)
content String?
published Boolean @default(false)
authorId Int
author User @relation(fields: [authorId], references: [id], onDelete: NoAction, onUpdate: NoAction)
}
model Profile {
id Int @id @default(autoincrement())
bio String?
userId Int @unique
user User @relation(fields: [userId], references: [id], onDelete: NoAction, onUpdate: NoAction)
}
model User {
id Int @id @default(autoincrement())
name String? @db.VarChar(255)
email String @unique @db.VarChar(255)
posts Post[]
profile Profile?
}
在此示例中,資料庫 schema 遵循了 Prisma ORM 模型的命名約定(只有透過內省生成的虛擬關係欄位不符合約定,需要調整)。這優化了生成的 Prisma Client API 的使用體驗。
使用自定義模型和欄位名稱
不過,有時你可能希望對 Prisma Client API 中公開的列和表的名稱進行額外更改。一個常見的例子是將資料庫 schema 中常用的snake_case命名法轉換為對 JavaScript/TypeScript 開發者來說更自然的PascalCase和camelCase命名法。
假設你從內省中獲得了以下基於snake_case命名法的模型
model my_user {
user_id Int @id @default(autoincrement())
first_name String?
last_name String @unique
}
如果你為這個模型生成了一個 Prisma Client API,它將在其 API 中使用snake_case命名法
const user = await prisma.my_user.create({
data: {
first_name: 'Alice',
last_name: 'Smith',
},
})
如果你不想在你的 Prisma Client API 中使用資料庫中的表名和列名,你可以使用@map和@@map來配置它們
model MyUser {
userId Int @id @default(autoincrement()) @map("user_id")
firstName String? @map("first_name")
lastName String @unique @map("last_name")
@@map("my_user")
}
透過這種方法,你可以隨意命名你的模型及其欄位,並使用@map(用於欄位名)和@@map(用於模型名)指向底層表和列。你的 Prisma Client API 現在看起來如下
const user = await prisma.myUser.create({
data: {
firstName: 'Alice',
lastName: 'Smith',
},
})
在配置你的 Prisma Client API頁面瞭解更多資訊。