第 2 篇:用 PostgreSQL 從零打造你的第一個 Prisma 專案

在第一篇裡,我們從巨觀視角認識了 Prisma。接下來這一篇,我們直接從一個真實專案起步:使用 Prisma 7 + Next.js 16.2.2 + PostgreSQL + pnpm,從空目錄走到「能在頁面上看到資料庫裡的第一條 User 記錄」。
你會完成:
建立一個 Next.js 16.2.2 專案(App Router);
設定 pnpm 作為套件管理器;
準備 PostgreSQL 資料庫;
初始化 Prisma 7(包含 prisma.config.ts);
定義第一個
User模型並遷移到資料庫;在 Next.js Server Component 中使用 Prisma Client 查詢並渲染資料。
完整命令總覽(速查)
先給這一篇用到的所有關鍵命令,一目了然:
# 1. 確認 / 安裝 pnpm
corepack enable
corepack prepare pnpm@latest --activate
# 2. 建立 Next.js 16.2.2 專案
pnpm create next-app@16.2.2 prisma-next-demo
cd prisma-next-demo
# 3. 安裝 Prisma 7 + PostgreSQL 相關依賴
pnpm add -D prisma tsx @types/node @types/pg
pnpm add @prisma/client @prisma/adapter-pg pg dotenv
# 4. 初始化 Prisma 7
pnpm prisma init
# 5. 根據 schema 產生並套用第一次遷移
pnpm prisma migrate dev --name init
# 6. 檢查遷移狀態(選用)
pnpm prisma migrate status
# 7. 開啟 Prisma Studio(視覺化插入資料)
pnpm prisma studio
# 8. 啟動 Next.js 開發服務
pnpm dev
後面正文會一步步解釋每條指令背後在做什麼。
1. 準備環境:Node.js、pnpm、PostgreSQL
1.1 Node.js 與 pnpm
確保你已經安裝了 Node.js(建議 18+),然後用 Corepack 開啟 pnpm:
corepack enable
corepack prepare pnpm@latest --activate
pnpm -v
看到版本號表示 pnpm 可用。
1.2 準備 PostgreSQL
你可以用任何方式提供 PostgreSQL,這裡給一個最常見的 Docker 範例:
docker run -itd \
-e POSTGRES_USER=prisma \
-e POSTGRES_PASSWORD=prisma \
-e POSTGRES_DB=next_prisma_demo \
-p 5432:5432 \
--name next-prisma-postgres \
postgres
我們約定:
使用者:
prisma密碼:
prisma資料庫:
next_prisma_demo埠號:
5432
後面 .env 中的 DATABASE_URL 會寫成:
DATABASE_URL="postgresql://prisma:prisma@localhost:5432/next_prisma_demo?schema=public"
如果你用的是雲端 PostgreSQL(Neon / Supabase / Railway / Prisma Postgres),把連線字串換掉即可。
2. 用 pnpm 建立 Next.js 16.2.2 專案
在你準備好的目錄裡執行:
pnpm create next-app@16.2.2 prisma-next-demo
cd prisma-next-demo
互動導引中,建議選擇:
TypeScript:Yes
ESLint:Yes
Tailwind CSS:可以 Yes(後續 UI 會舒服很多)
使用
src/目錄:隨意,這裡下面範例假設 不使用 src,即app/在根目錄下; nextjsApp Router:Yes
Import alias:保留預設
@/*。
這一步結束後,你已經有了一個 Next.js 16.2.2 App Router 專案骨架。
3. 安裝 Prisma 7 與 PostgreSQL 相關依賴
根據 Prisma 7 官方 Postgres Quickstart 的推薦,我們需要:CLI + Client + PostgreSQL adapter + 驅動。
在專案裡執行:
pnpm add -D prisma tsx @types/node @types/pg
pnpm add @prisma/client @prisma/adapter-pg pg dotenv
角色說明:
prisma:CLI 工具(pnpm prisma ...);@prisma/client:根據 schema 產生的 TypeScript 用戶端;@prisma/adapter-pg:Prisma 7 推薦的 PostgreSQL 驅動介面卡;pg:node-postgres 驅動;dotenv:讀取.env;tsx:以後寫 seed 腳本會很方便。
4. 初始化 Prisma 7:產生設定與 schema
Prisma 7 推薦使用 prisma init 來產生包含 prisma.config.ts 在內的一套預設設定。
在專案根目錄執行:
pnpm prisma init
執行後你會看到多了這些檔案:
prisma/schema.prismaprisma.config.ts.env
這三個檔案分別承擔:
Schema:描述資料模型;
Config:告知 Prisma CLI schema/migrations/資料來源等設定;
.env:提供
DATABASE_URL這樣的環境變數。
4.1 設定 .env 中的 DATABASE_URL
開啟 .env,按照前面準備的 PostgreSQL 填入連線字串:
DATABASE_URL="postgresql://prisma:prisma@localhost:5432/next_prisma_demo?schema=public"
如果使用 Prisma Postgres,這裡就填 Prisma 控制檯裡提示的 PostgreSQL 連線 URL。注意使用 postgresql:// 形式。
4.2 設定 prisma.config.ts
Prisma 官方 Next.js 指南中給出的設定方式大致如下:
// prisma.config.ts
import 'dotenv/config'
import { defineConfig, env } from 'prisma/config'
export default defineConfig({
schema: 'prisma/schema.prisma',
migrations: {
path: 'prisma/migrations',
},
datasource: {
url: env('DATABASE_URL'),
},
})
這段設定說明:
Prisma CLI 使用
prisma/schema.prisma作為 schema 檔案;資料庫遷移存放在
prisma/migrations;資料來源 URL 從環境變數
DATABASE_URL讀取;使用
dotenv/config自動載入.env。
5. 撰寫第一個 Prisma Schema:User 模型
開啟 prisma/schema.prisma,改成一個最小可用的版本:
// prisma/schema.prisma
generator client {
provider = "prisma-client"
output = "../generated/prisma"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
name String
email String @unique
createdAt DateTime @default(now())
}
這裡有幾個點:
使用
provider = "prisma-client",搭配自訂output目錄../generated/prisma是 Prisma 7 的推薦寫法之一;datasource 明確為
postgresql;User模型包含:自增 Int 主鍵
id;普通字串欄位
name;帶唯一約束的
email;自動填入目前時間的
createdAt。
後面所有 Prisma Client 的型別、安全性等,都源自於這個 schema。
6. 產生並套用第一次遷移(開發環境)
Prisma 官方推薦的工作流程是:開發環境用 migrate dev,生產環境用 migrate deploy。
在專案根目錄執行:
pnpm prisma migrate dev --name init
它會:
根據當前
schema.prisma和資料庫狀態產生一個遷移;把遷移 SQL 寫入
prisma/migrations/*/migration.sql;套用到你的 PostgreSQL 資料庫;
產生或更新 Prisma Client。
如果執行成功,你可以順便看一下遷移狀態:
pnpm prisma migrate status
它會顯示哪些遷移已套用、目前資料庫是否與 schema 同步。
面向生產環境的提醒(以後會詳細展開):
開發環境用migrate dev很舒服,但生產環境請只用migrate deploy,並把它放進 CI/CD 管線,而不是在維運機上手動執行。
7. 在 Next.js 中建立 Prisma Client 單例
為了在 Next.js(尤其是開發環境有熱重載)中安全地使用 Prisma Client,官方 Next.js 指南推薦採用「單例 + adapter」的寫法。
在專案中新建 lib/prisma.ts:
// lib/prisma.ts
import { PrismaClient } from '../generated/prisma'
import { PrismaPg } from '@prisma/adapter-pg'
const connectionString = process.env.DATABASE_URL
if (!connectionString) {
throw new Error('DATABASE_URL is not set')
}
const adapter = new PrismaPg({ connectionString })
const globalForPrisma = globalThis as unknown as {
prisma?: PrismaClient
}
export const prisma =
globalForPrisma.prisma ??
new PrismaClient({
adapter,
})
if (process.env.NODE_ENV !== 'production') {
globalForPrisma.prisma = prisma
}
這一段程式碼體現了幾個關鍵理念:
使用
PrismaPgadapter 把 Prisma Client 接到 PostgreSQL;在開發環境下,把 PrismaClient 實例掛到
globalThis上,避免 Next.js 熱重載時建立過多連線;在生產環境中正常建立一個實例,不汙染全域。
後續整個專案只需要從 lib/prisma 匯入 prisma,不用再重複建立。
8. 在 Next.js 首頁做第一次資料庫查詢
接下來,我們在 app/page.tsx 裡用 Prisma 查詢 User 表,並在頁面上渲染結果。
編輯 app/page.tsx:
// app/page.tsx
import { prisma } from '@/lib/prisma'
export default async function Home() {
const users = await prisma.user.findMany({
orderBy: { createdAt: 'desc' },
})
return (
<main style={{ padding: '32px' }}>
<h1>Prisma 7 + Next.js 16.2.2 + PostgreSQL</h1>
<p>當前使用者數量:{users.length}</p>
<ul>
{users.map((u) => (
<li key={u.id}>
{u.name} - {u.email}
</li>
))}
</ul>
</main>
)
}
因為這是一個 Server Component(預設就是),可以直接在函式本體裡使用 await prisma.user.findMany,這一點是 Next.js App Router 與 Prisma 搭配時非常自然的地方。
現在唯一的問題是資料庫裡還沒有使用者資料,我們馬上來補一條。
9. 用 Prisma Studio 插入第一條 User
Prisma Studio 是官方提供的 Web UI,可以在瀏覽器裡直接檢視和編輯資料。
在專案根目錄執行:
pnpm prisma studio
瀏覽器會開啟一個介面,左側可以看到 User 表:
點選
User;點選「Add Record」;
填寫例如:
name:
Aliceemail:
alice@example.com;
儲存。
回到終端機,啟動 Next.js 開發伺服器:
pnpm dev
開啟瀏覽器造訪 http://localhost:3000,你應該會看到:
標題;
「當前使用者數量:1」;
列表裡有
Alice - alice@example.com。
到這裡,這條完整鏈路已經打通:瀏覽器 → Next.js App Router → Prisma Client → PostgreSQL → 回傳資料 → 頁面渲染。
10. package.json 範例(Prisma + Next.js + pnpm 情境)
為了方便你對照,這裡給一個典型的 package.json 片段(只保留和這一篇相關部分),你可以按需調整:
{
"name": "prisma-next-demo",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint",
"prisma:generate": "prisma generate",
"prisma:migrate": "prisma migrate dev",
"prisma:deploy": "prisma migrate deploy",
"prisma:studio": "prisma studio"
},
"dependencies": {
"@prisma/adapter-pg": "^7.0.0",
"@prisma/client": "^7.0.0",
"dotenv": "^16.0.0",
"next": "16.2.2",
"pg": "^8.0.0",
"react": "18.3.1",
"react-dom": "18.3.1"
},
"devDependencies": {
"@types/node": "^22.0.0",
"@types/pg": "^8.0.0",
"prisma": "^7.0.0",
"tsx": "^4.0.0",
"typescript": "^5.0.0"
}
}
版本號你可以按實際安裝結果調整(
^7.0.0只表示是 Prisma 7 大版本);把
prisma:migrate/prisma:deploy腳本加進去,後續 CI/CD 會更方便呼叫。
11. 常見錯誤與排查思路
11.1 Error: P1001 無法連線資料庫
典型錯誤內容會包含「The database server was reached but timed out」或「Cannot reach database server」。常見原因:
Docker 容器沒啟動 / PostgreSQL 沒跑起來;
.env裡的DATABASE_URL寫錯(使用者名稱/密碼/資料庫名稱/埠號);資料庫防火牆規則限制(遠端雲端資料庫時)。
排查建議:
確認 Docker 容器在執行:
docker ps;用 psql / GUI 工具單獨連一次資料庫確認連線字串正確;
確保 Next.js 專案和資料庫在網路上可互通。
11.2 Error: DATABASE_URL is not set
在 lib/prisma.ts 裡我們主動檢查了 process.env.DATABASE_URL,如果沒有就拋錯。
常見原因:
.env檔案沒建立;.env在錯誤路徑(不是專案根目錄);啟動指令不在專案根目錄執行。
排查建議:
確認
.env與package.json在同一目錄;確認是從專案根目錄執行
pnpm dev;重啟開發伺服器讓環境變數重新載入。
11.3 relation "User" does not exist
表示資料庫裡還沒有對應的資料表,但你已經呼叫了查詢。常見原因:忘記跑 migrate dev 或 migrate deploy。
解決方案:
pnpm prisma migrate dev --name init
之後重新啟動 pnpm dev。
11.4 Next.js 開發環境連線數過多 / warn
如果你在開發時頻繁看到類似「too many clients already」的 Postgres 錯誤,通常是 PrismaClient 被多次 new 導致連線池累積。
解決方案:
確認
lib/prisma.ts使用了全域單例模式(globalThis.prisma);確認所有地方都是
import { prisma } from '@/lib/prisma',沒有自己手動new PrismaClient。
12. 小結:這一篇之後,你已經有了「可擴展」的專案起點
這一篇我們有意識地把「從零跑通 Prisma」這件事放在了 Prisma 7 + Next.js 16.2.2 + pnpm + PostgreSQL 的組合裡,而不是單獨的腳本專案,這樣後續所有實戰篇(Next.js、MCP、AI 輔助開發)都能順暢銜接。
此時你已經擁有:
一個現代化的 Next.js App Router 專案骨架;
一套 PostgreSQL 資料庫和可追蹤的遷移歷史;
一個基於 Prisma 7、適配 PostgreSQL 的 Client 單例;
第一條從頁面發出的、型別安全的資料庫查詢。
參考連結
Prisma文件
https://www.prisma.io/docs/getting-started/prisma-orm/quickstart/postgresql
https://www.prisma.io/docs/guides/use-prisma-in-pnpm-workspaces
https://www.prisma.io/docs/orm/prisma-migrate/workflows/development-and-production
Github
在 Google 上持續關注
把 HeyBinyang 加入 Google 首選來源
如果你希望之後在 Google 上更容易看到我的更新,可以把這個站點加入 preferred source,讓它在相關閱讀情境裡更容易被找到。
SHARE
分享
分享這篇文章。