技術1 閱讀

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

在第一篇裡,我們從巨觀視角認識了 Prisma。接下來這一篇,我們直接從一個真實專案起步:使用 Prisma 7 + Next.js 16.2.2 + PostgreSQL + pnpm,從空目錄走到「能在頁面上看到資料庫裡的第一條 User 記錄」。

你會完成:


完整命令總覽(速查)

先給這一篇用到的所有關鍵命令,一目了然:

text
# 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:

text
corepack enable
corepack prepare pnpm@latest --activate
pnpm -v

看到版本號表示 pnpm 可用。

1.2 準備 PostgreSQL

你可以用任何方式提供 PostgreSQL,這裡給一個最常見的 Docker 範例:

text
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

我們約定:

後面 .env 中的 DATABASE_URL 會寫成:

text
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 專案

在你準備好的目錄裡執行:

text
pnpm create next-app@16.2.2 prisma-next-demo
cd prisma-next-demo

互動導引中,建議選擇:

這一步結束後,你已經有了一個 Next.js 16.2.2 App Router 專案骨架。


3. 安裝 Prisma 7 與 PostgreSQL 相關依賴

根據 Prisma 7 官方 Postgres Quickstart 的推薦,我們需要:CLI + Client + PostgreSQL adapter + 驅動。

在專案裡執行:

text
pnpm add -D prisma tsx @types/node @types/pg
pnpm add @prisma/client @prisma/adapter-pg pg dotenv

角色說明:


4. 初始化 Prisma 7:產生設定與 schema

Prisma 7 推薦使用 prisma init 來產生包含 prisma.config.ts 在內的一套預設設定。

在專案根目錄執行:

text
pnpm prisma init

執行後你會看到多了這些檔案:

這三個檔案分別承擔:

4.1 設定 .env 中的 DATABASE_URL

開啟 .env,按照前面準備的 PostgreSQL 填入連線字串:

text
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 指南中給出的設定方式大致如下:

text
// 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'),
  },
})

這段設定說明:


5. 撰寫第一個 Prisma Schema:User 模型

開啟 prisma/schema.prisma,改成一個最小可用的版本:

text
// 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())
}

這裡有幾個點:

後面所有 Prisma Client 的型別、安全性等,都源自於這個 schema。


6. 產生並套用第一次遷移(開發環境)

Prisma 官方推薦的工作流程是:開發環境用 migrate dev,生產環境用 migrate deploy

在專案根目錄執行:

text
pnpm prisma migrate dev --name init

它會:

如果執行成功,你可以順便看一下遷移狀態:

text
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

text
// 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
}

這一段程式碼體現了幾個關鍵理念:

後續整個專案只需要從 lib/prisma 匯入 prisma,不用再重複建立。


8. 在 Next.js 首頁做第一次資料庫查詢

接下來,我們在 app/page.tsx 裡用 Prisma 查詢 User 表,並在頁面上渲染結果。

編輯 app/page.tsx

text
// 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,可以在瀏覽器裡直接檢視和編輯資料。

在專案根目錄執行:

text
pnpm prisma studio

瀏覽器會開啟一個介面,左側可以看到 User 表:

  1. 點選 User

  2. 點選「Add Record」;

  3. 填寫例如:

  1. 儲存。

回到終端機,啟動 Next.js 開發伺服器:

text
pnpm dev

開啟瀏覽器造訪 http://localhost:3000,你應該會看到:

到這裡,這條完整鏈路已經打通:瀏覽器 → Next.js App Router → Prisma Client → PostgreSQL → 回傳資料 → 頁面渲染


10. package.json 範例(Prisma + Next.js + pnpm 情境)

為了方便你對照,這裡給一個典型的 package.json 片段(只保留和這一篇相關部分),你可以按需調整:

text
{
  "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"
  }
}

11. 常見錯誤與排查思路

11.1 Error: P1001 無法連線資料庫

典型錯誤內容會包含「The database server was reached but timed out」或「Cannot reach database server」。常見原因:

排查建議:

11.2 Error: DATABASE_URL is not set

lib/prisma.ts 裡我們主動檢查了 process.env.DATABASE_URL,如果沒有就拋錯。

常見原因:

排查建議:

11.3 relation "User" does not exist

表示資料庫裡還沒有對應的資料表,但你已經呼叫了查詢。常見原因:忘記跑 migrate devmigrate deploy

解決方案:

text
pnpm prisma migrate dev --name init

之後重新啟動 pnpm dev

11.4 Next.js 開發環境連線數過多 / warn

如果你在開發時頻繁看到類似「too many clients already」的 Postgres 錯誤,通常是 PrismaClient 被多次 new 導致連線池累積。

解決方案:


12. 小結:這一篇之後,你已經有了「可擴展」的專案起點

這一篇我們有意識地把「從零跑通 Prisma」這件事放在了 Prisma 7 + Next.js 16.2.2 + pnpm + PostgreSQL 的組合裡,而不是單獨的腳本專案,這樣後續所有實戰篇(Next.js、MCP、AI 輔助開發)都能順暢銜接。

此時你已經擁有:

參考連結

Prisma文件

  1. https://www.prisma.io/docs/guides/nextjs

  2. https://www.prisma.io/docs/guides/frameworks/nextjs

  3. https://www.prisma.io/docs/getting-started/prisma-orm/quickstart/postgresql

  4. https://www.prisma.io/docs/cli/migrate/deploy

  5. https://www.prisma.io/docs/guides/use-prisma-in-pnpm-workspaces

  6. https://www.prisma.io/docs/orm/prisma-migrate/workflows/development-and-production

Github

  1. https://github.com/prisma/prisma/discussions/24571

SHARE

分享

分享這篇文章。