在 nodeJs 使用 Prisma ORM

更新 發佈閱讀 19 分鐘

前言

這裡主要是記錄我想把學習在 node.js 使用 prisma 中的踩坑紀錄,把整個過程整理成筆記。

範本程式碼我放在 這裡

環境建立

1. 建立專案資料夾

mkdir node-prisma-pg
cd ./node-prisma-pg

2. 設定 mpn 環境

npm init -y

3. 修改 package.json 使用 esm

因為整份專案會使用 es module 模式來開發,且未來專案對於 commonJS 支援將會越來越少,所以目前我的專案除非是特別理由,一律優先考慮使用 esm 模式開發。

將 package.json 的 "type": "commonjs" 改為 "type": "module"

4. 安裝 TypeScript 套件及初始化 TypeScript 環境

npm install typescript tsx @types/node --save-dev

  • typescript: 專案專用的 typescript 套件,可以依需求指定版本。
  • tsx: 在沒有編譯檔案,直接執行 TypeScript,底層用 esbuild 來編譯。
  • @types/node: node.js 的 types 宣告檔。

初始化 TypeScript 環境

npx tsc --init

會在專案資料夾根目錄產生 tsconfig.json 這個 TypeScript 環境設定檔,稍後會修改內部內容以符合專案環境所需設定。

5. 安裝 prisma 相依套件

目前踩到最大的坑,因為一開始安裝時候沒有指定版本,導致無法使用 Prisma

 這裡我遇到的問題是 prisma 各大版本的架構差異極大,如果不指定 prisma@prisma/client 套件版本可能不一樣,會有無法使用的問題。

 截至目前為止(2025-11-29), prisma 大版本已經到 7 ,且底層程式碼全改為 rust 改寫,但目前尚不穩定,且每次改版結構變動會非常大,engine 設定與 CLI 改動很多,相關文件和相依套件尚未補齊,也還沒有,尚未有 LTS(Long-term support) 版本出現,所以目前專案鎖定使用 Prisma 6 這個版本。

npm install prisma@6 @types/pg --save-dev

  • prisma@6: Prisma CLI 工具,指定使用 6 大版號
  • @types/pg: PostgreSQL types 宣告檔案

npm install @prisma/client@6 pg dotenv

  • @prisma/client@6: Prisma 用戶端套件,用於操作資料庫使用,其指定大版號需與 Prisma CLI 工具一致
  • pg: PostgreSQL engine 用於操作 PostgreSQL 資料庫
  • dotenv: 用於讀取 .env 環境變數資料,然後設定入環境變數當中

6. 修改 tsconfig.json 支援 node.js 及 esm 環境

以下是修改後的 tsconfig.json ,各位可以看著跟修改成一樣的內容

{
  // Visit https://aka.ms/tsconfig to read more about this file
  "compilerOptions": {
    // File Layout
    "rootDir": "./src",
    "outDir": "./dist",
    // Environment Settings
    // See also https://aka.ms/tsconfig/module
    "module": "NodeNext", // esm 模式要用 NodeNext ,才會檢查路徑附檔名,還有型別引入是否有使用 import type {} 等等
                          // 還有編譯時對 .ts/.tsx/.mts/.cts → .js/.jsx/.mjs/.cjs 對應映射,符合 Node ESM ,英文大小寫要完全相同
    "target": "esnext",
    // "types": [],
    // For nodejs:
    "lib": ["esnext"],
    "types": ["node"],
    "moduleResolution": "NodeNext", // 新增
    "esModuleInterop": true, // 新增
    // and npm install -D @types/node
    // Other Outputs
    "sourceMap": false,
    "declaration": false,
    "declarationMap": false,
    // Stricter Typechecking Options
    "noUncheckedIndexedAccess": true,
    "exactOptionalPropertyTypes": true,
    // Style Options
    // "noImplicitReturns": true,
    // "noImplicitOverride": true,
    // "noUnusedLocals": true,
    // "noUnusedParameters": true,
    // "noFallthroughCasesInSwitch": true,
    // "noPropertyAccessFromIndexSignature": true,
    // Recommended Options
    "strict": true,
    "jsx": "react-jsx",
    "verbatimModuleSyntax": true,
    "isolatedModules": true,
    "noUncheckedSideEffectImports": true,
    "moduleDetection": "force",
    "skipLibCheck": true
  },
  "include": ["src"], // 新增
  "exclude": ["dist"] // 新增
}

開始設定 Prisma 執行環境

1. 先建立專案 TypeScript 原始檔資料夾

mkdir src

2. Prisma 環境初始化

透過 --datasource-provider postgresql 指定使用 postgreSQL

資料庫使用的 DBMS 以後可以在 prisma/schema.prisma 設定檔內更改

npx prisma init --datasource-provider postgresql

初始化後會產生以下檔案和目錄:

  • prisma/schema.prisma
  • prisma.config.ts
  • .env
  • .gitignore

在後面會根據需要修改部分內容

3. 修改 .env 檔案的 DATABASE_URL 環境變數

DATABASE_URL="postgresql://username:password@localhost:5432/mydb?schema=public"

username 跟 password 就依據要給 prisma ORM 用的帳號設定

mydb: 為要連線的資料庫名稱

4. 定義資料表結構,以及執行 migration

補充說明: prisma 的 migration 跟 sequelize migration 不同

sequelize 在撰寫完 migration 檔案後,再要執行 migration 指令,之後還要自己更改 module ,與資料庫最新結構對應。

prisma migration 事先修改 schema.prisma(這是唯一的真實資料模型),然後再執行 migration 指令,會在比較 schema.prisma 差異後,自動產生 SQL migration 檔案執行 migration更新 Prisma Client (自動生成型別)。讓開發者只需要專注於資料模型即可。

修改 `prisma/schema.prisma` 內容,在 `prisma/schema.prisma` 新增資料庫資料表定義。

// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init

generator client {
  provider = "prisma-client"
  output   = "../src/generated"
}

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

model User {
  id    Int     @id @default(autoincrement())
  email String  @unique
  name  String?
  posts Post[]
  @@map("users")
}

model Post {
  id        Int     @id @default(autoincrement())
  title     String
  content   String?
  published Boolean @default(false)
  author    User    @relation(fields: [authorId], references: [id])
  authorId  Int
  @@map("posts")
}

補充 Prisma 的 migration 不會對資料表名稱自動做單複數轉換

在 sequelize 的 migration 檔案除非設定 freezeTableName: true ,或使用優先度更高的 tableName: tables 不然在建立資料表的時候,會做資料表名稱的單複數轉換,所以在使用 sequelize 時候, migration 檔案會使用單數名詞,生成的資料表名稱會自動轉為複數名詞。

但是在 prisma 的 migration 並不會做資料表名稱的單複數轉換,因為在 prisma 的設計理念是:

  • schema 就是事實來源(single source of truth)
  • 裡面寫什麼,migration 就會建什麼
  • 不自動改名,避免神秘行為(magic behavior)
  • 跨 DB 更一致(PostgreSQL, MySQL, SQLite 都一樣)

所以如果想要讓 prisma 建立的資料表名稱可以符合一般 SQL 使用慣例,用複數名詞命名的話,可以使用 @@map("英文複數名詞") 來指定資料表名稱。

5. 之後執行 migration 指令

執行 migration 指令,生成 migration 檔案

npx prisma migrate dev --name init

因為尚未有 migrate 檔案,所以需要指定 --name 檔案名稱,如果沒有該參數,會開啟對話要求輸入名稱,程序才會繼續, ​prisma 不會幫你命名檔案名稱。

6. 使用 npx prisma generate 產生 prisma client 資料庫操作模型

不過在上一步驟程序已經包含在內了,可以略過此步驟

npx prisma generate

每次有修改 schema , migrate 之後一定要執行,這樣才可以讓 prisma client 對應到最新的 schema ,不過在 migrate 指令已經包含此步驟。

7. 實例化 Prisma 客戶端

現在所有相依性都已安裝完畢,可以實例化 Prisma Client 了。

建立 src/lib/prisma.ts ,以下是該檔案的內容

import "dotenv/config";
import { PrismaClient } from '../generated/client'

// Prisma v6 會自動使用 DATABASE_URL
const prisma = new PrismaClient();

export { prisma }

之後在需要使用 Prisma client 的檔案只要 import 該檔案就可以使用 prisma 引擎操作資料庫了。

8. 建立 prisma seed 檔案

要先要到 prisma.config.ts 設定 seed 指令的執行方式

import "dotenv/config";
import { defineConfig, env } from "prisma/config";

export default defineConfig({
  schema: "prisma/schema.prisma",
  migrations: {
    path: "prisma/migrations",
    seed: "tsx prisma/seed.ts", // 新增這行
  },

  engine: "classic",
  datasource: {
    url: env("DATABASE_URL"),
  },
});

這裡是設定要用什麼套件執行 seed 檔案,以及 seed 檔案的路徑。

prisma seed 在 typescript 可以用不同套件執行 .ts 的 seed 檔案,如: ts-node 、 tsx 或是 v22.6.0 以後版本的 node

以上這種設定方式是在 prisma v6.13.0 版本中宣佈正式支援,更早期的版本是設定在 package.json 當中

"prisma": {
  "seed": "tsx prisma/seed.ts"
}

新增及編輯 prisma\seed.ts 檔案

因為我把範例檔案改成使用 transaction ,所以部分內容會不太一樣

import { prisma } from "./lib/prisma";

async function main() {
  // Create a new user with a post
  const user = await prisma.user.create({
    data: {
      name: "Alice",
      email: "[email protected]",
      posts: {
        create: {
          title: "Hello World",
          content: "This is my first post!",
          published: true,
        },
      },
    },
    include: {
      posts: true,
    },
  });
  console.log("Created user:", user);

  // Fetch all users with their posts
  const allUsers = await prisma.user.findMany({
    include: {
      posts: true,
    },
  });

  console.log("All users:", JSON.stringify(allUsers, null, 2));
}

main()
  .then(async () => {
    await prisma.$disconnect();
  })
  .catch(async (e) => {
    console.error(e);
    await prisma.$disconnect();
    process.exit(1);
  });

執行 seed 指令

可以用 typescript 套件或是 prisma CLI 執行 seed 檔案

直接執行 seed 檔案

tsx prisma/seed.ts

prisma CLI 執行 seed 檔案

npx prisma db seed

9. 使用 Prisma Studio 查看建立的數據資料庫

npx prisma studio --config ./prisma.config.ts

將打開一個網頁介面,您可以在其中查看和編輯您資料庫當中的資料。

留言
avatar-img
weijie 的各種記事
0會員
7內容數
原本是打算用來當作技術部落格的,不過以後也會把各種雜記紀錄於此
你可能也想看
Thumbnail
準備專案 這邊首先準備一個新的專案,可以參考react官網,完成後參考README.md輸入npm run dev就可以啟動並在瀏覽器看到畫面 準備nssm工具 在google上搜nssm,第一個項目點進去後,找到並下載穩定版,附上下載鏈接 壓縮檔下載完畢後,解壓縮到喜歡的地方,然後進入資料
Thumbnail
準備專案 這邊首先準備一個新的專案,可以參考react官網,完成後參考README.md輸入npm run dev就可以啟動並在瀏覽器看到畫面 準備nssm工具 在google上搜nssm,第一個項目點進去後,找到並下載穩定版,附上下載鏈接 壓縮檔下載完畢後,解壓縮到喜歡的地方,然後進入資料
Thumbnail
NodeJS作用? NodeJS 作為一個後端程式語言,與伺服器交互,能夠開發服務器應用、開發工具類應用,例如:Webback、Vite 這些好用工具,或是透過NodeJS的electron框架開發桌面端應用,而常見的桌面端應用如 VScode
Thumbnail
NodeJS作用? NodeJS 作為一個後端程式語言,與伺服器交互,能夠開發服務器應用、開發工具類應用,例如:Webback、Vite 這些好用工具,或是透過NodeJS的electron框架開發桌面端應用,而常見的桌面端應用如 VScode
Thumbnail
NodeJS 學習來到 file systems 操作,在文檔操作上有分為同步跟異步的處理,接下來分階段介紹操作函數
Thumbnail
NodeJS 學習來到 file systems 操作,在文檔操作上有分為同步跟異步的處理,接下來分階段介紹操作函數
Thumbnail
這篇想來寫,剛碰到js得時候,為了讓程式可以運作而安裝Node.js 。Node.js 是能夠在伺服器上面運行 JavaScript 的應用平台環境,透過 Node.js 提供的函式庫與執行環境能完成伺服器端服務。此篇幅就直接從純後端的角度切入摟(對不起拉我寫來寫去還是不知道怎麼順順的寫好文章開頭Q
Thumbnail
這篇想來寫,剛碰到js得時候,為了讓程式可以運作而安裝Node.js 。Node.js 是能夠在伺服器上面運行 JavaScript 的應用平台環境,透過 Node.js 提供的函式庫與執行環境能完成伺服器端服務。此篇幅就直接從純後端的角度切入摟(對不起拉我寫來寫去還是不知道怎麼順順的寫好文章開頭Q
Thumbnail
《轉轉生》(Re:INCARNATION)為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,結合拉各斯街頭節奏、Afrobeat/Afrobeats、以及約魯巴宇宙觀的非線性時間,建構出關於輪迴的「誕生—死亡—重生」儀式結構。本文將從約魯巴哲學概念出發,解析其去殖民的身體政治。
Thumbnail
《轉轉生》(Re:INCARNATION)為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,結合拉各斯街頭節奏、Afrobeat/Afrobeats、以及約魯巴宇宙觀的非線性時間,建構出關於輪迴的「誕生—死亡—重生」儀式結構。本文將從約魯巴哲學概念出發,解析其去殖民的身體政治。
Thumbnail
最近跟著影片學習NodeJS,第一部分先學習對Buffer的處理跟理解,以下是對於NodeJS Buffer的理解筆記
Thumbnail
最近跟著影片學習NodeJS,第一部分先學習對Buffer的處理跟理解,以下是對於NodeJS Buffer的理解筆記
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
安裝完成 nodejs 後選用一個工作目錄執行 npm init,npm 會產生一個 package.json 檔案,之後為此專案安裝套件時都會記錄在此,讓專案可以很容易的重建和移植,也可設定 npm start 執行時以哪一個 js 檔當作系統入口。直接開寫了,以下我用 app.js 當作系統入口
Thumbnail
安裝完成 nodejs 後選用一個工作目錄執行 npm init,npm 會產生一個 package.json 檔案,之後為此專案安裝套件時都會記錄在此,讓專案可以很容易的重建和移植,也可設定 npm start 執行時以哪一個 js 檔當作系統入口。直接開寫了,以下我用 app.js 當作系統入口
Thumbnail
這一篇文章,我想來談談模板語言(template language/engine)。而其中比較有名的為handlebar、pug、ejs。那我會的事後兩著,因此拿這兩個出來寫一篇文章。 Pug 指令:npm install pug 比起 HTML 的語法,pug 語法可以說簡潔很多。 那下面
Thumbnail
這一篇文章,我想來談談模板語言(template language/engine)。而其中比較有名的為handlebar、pug、ejs。那我會的事後兩著,因此拿這兩個出來寫一篇文章。 Pug 指令:npm install pug 比起 HTML 的語法,pug 語法可以說簡潔很多。 那下面
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
由於Javascript本身設計就適合於單線程的應用, 但一般後端應用程式都會支援多個服務來處理client的請求, nodejs中也提供了cluster模組來達成此功能。 Cluster的原理很簡單,由於每個Process都只能用單核心的CPU來運行,那麼就多開幾個來幫忙處理吧! 而這個Clust
Thumbnail
由於Javascript本身設計就適合於單線程的應用, 但一般後端應用程式都會支援多個服務來處理client的請求, nodejs中也提供了cluster模組來達成此功能。 Cluster的原理很簡單,由於每個Process都只能用單核心的CPU來運行,那麼就多開幾個來幫忙處理吧! 而這個Clust
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News