返回文章列表
nodejstypescript

Prisma

Prisma使用教學

2026年4月7日 2 次瀏覽 haodai
Prisma

1. 安裝NPM

bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# npm初始化
npm init -y

# 安裝TypeScript
npm install typescript ts-node @types/node --save-dev
npx tsc --init

# 安裝Prisma CLI
npm install prisma --save-dev

# 安裝Prisma Client
npm install @prisma/client

##### Prisma初始化
npx prisma init

2. .env

bash
1
2
DATABASE_URL="mysql://{user}:{password}@{localhost}:3306/mydb"

3. 設置環境schema.prisma

bash
1
2
3
4
5
6
7
8
9
10
generator client {
  provider = "prisma-client-js"
}

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

3-1. 撰寫Schema(schema.prisma)

bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
....

### 設定 Model
## 關聯 []
## 選填 ?
## Int,String,Boolean,Float還有 DateTime
model User {
  id           Int        @id @default(autoincrement())
  type         String     @db.VarChar(10)
  tel          String     @db.VarChar(20) @unique
  password     String?    @db.VarChar(255)
  created_at   DateTime   @default(now())
  updated_at   DateTime?  @updatedAt
  orders       Order[]
}

model Order {
  id           Int        @id @default(autoincrement())
  user_id      Int
  user         User       @relation(fields: [user_id], references: [id])
  ## user [要連結的table] @relation(fields: [自己的哪個Column要做連線], references: [要連到目標table的哪個Column])
  content      Json       @db.Json
  remark       String?    @db.VarChar(100)
  amount       Decimal    @db.Decimal(6,0)
  created_at   DateTime   @default(now())
}

## 多對多範例: 自動生成多對多資料表
model Post {
  id           Int        @id @default(autoincrement())
  comments     Comment[]
}
model Comment {
  id           Int        @id @default(autoincrement())
  posts        Post[]
}

## 多對多: 自訂生成多對多資料表
model CommentsOnPosts {
  post         Post     @relation(fields: [post_id], references: [id])
  post_id      Int
  comment      Comment  @relation(fields: [comment_id], references: [id])
  comment_id   Int
  assigned_at  DateTime @default(now())
  assigned_by  String

  @@id([post_id, comment_id])
}

3-1-1. 特殊語法 @@map / @map

bash
1
2
3
4
5
6
7
8
9
10
11
12
## 這兩個 map 都是拿來重命名,@map 是針對 Column 重命名,而 @@map 是針對 table 重命名
model User {
	id Int @id
	cardId Int @map("card_id")
	@@map("user")
}
#等同於:
model user {
	id Int @id
	card_id Int
}

3-1-2. 特殊語法 @default

bash
1
2
3
4
5
6
7
8
## 預設值
#   @default(autoincrement())
#   @default(now())
#   @defalut(true)
model User {
	id Int @id @default(autoincrement())
}

3-1-3. 特殊語法 @id / @@id

bash
1
2
3
4
5
6
7
8
9
10
## @id 代表主鍵(PK),@@id 則是一次設立多個主鍵
model Table {
  id Int @id @default(autoincrement())
}
model Table {
  firstName String
  lastName String
  @@id([firstName, lastName])
}

3-1-4. 特殊語法 @unique / @@unique

bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
## 跟 id 一樣,分為一個跟多個唯一值
model User {
  id Int @id @default(autoincrement())
  email String? @unique
  name String
}
model User {
  id Int @id
  first_name Int
  last_name Int
  card Int?

  @@unique([first_name, last_name])
}

3-1-5. 特殊語法 @relation

bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
## relation 代表的是外鍵約束
model User {
  id Int @id
  first_name String
  last_name String
  Post Post[]
}
model Post {
  id Int @id
  author User @relation(fields: [userId], references: [id])
  content String
  userId Int
}

3-2. 依已存在資料庫生成Schema

bash
1
2
3
4
npx prisma db pull

# 檢查Schema邏輯

4. 生成migrate / 遷移 / 退回

bash
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
## (實驗性功能) 生成migrate
npx prisma migrate save --name init --experimental

## (實驗性功能) migrate遷移 至最新
npx prisma migrate up --experimental

## (實驗性功能) migrate遷移 2個階段
npx prisma migrate up 2 --experimental

## (實驗性功能) migrate回退 2個階段
prisma migrate down 2 --experimental

## 生成migrate並遷移
npx prisma migrate dev --name init

## 用於關聯資料庫,檢查Schema與DB之間的差異後,生成資料庫遷移,並將其套用到資料庫
npx prisma db push
## 解析Schema並生成Prisma Client
npx prisma generate

5. Prisma Client – GUI

bash
1
2
npx prisma studio

6. 建立Seeder

plain
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
## prisma/seeder.ts
const { PrismaClient } = require('@prisma/client')
const prisma = new PrismaClient()

const menu = [
  {
    title: '海鮮粥',
    price: '100',
    is_published: true,
    is_purchased: true
  },
  {
    title: '廣東粥',
    price: '100',
    is_published: true,
    is_purchased: false
  }
]

async function main() {
  await prisma.user.deleteMany()
  await prisma.product.deleteMany()
  await prisma.setting.deleteMany()

  const user = await prisma.user.create({
    data: {
      type: 'admin',
      name: '管理員',
      email: 'iZO.tw@mail.com',
      password: '1234'
    }
  })
  const product = await prisma.product.createMany({
    data: menu
  })
  console.log({ user, product })
}
main()
  .then(async () => {
    await prisma.$disconnect()
  })
  .catch(async (e) => {
    console.error(e)
    await prisma.$disconnect()
    process.exit(1)
  })

## work
node ./prisma/seeder.ts