資料填充 (Seeding)
本指南說明如何使用 Prisma Client 和 Prisma ORM 整合的資料填充功能來填充您的資料庫。資料填充讓您可以一致地重新建立資料庫中的相同資料,並且可以用於
- 使用應用程式啟動所需的資料(例如預設語言或貨幣)來填充您的資料庫。
- 為在開發環境中驗證和使用您的應用程式提供基本資料。如果您正在使用 Prisma Migrate,而有時需要重置您的開發資料庫,這特別有用。
如何在 Prisma ORM 中填充您的資料庫
Prisma ORM 整合的資料填充功能預期在您 package.json
檔案的 "prisma"
鍵中的 "seed"
鍵中有一個命令。這可以是任何命令,prisma db seed
只會執行它。在本指南中以及作為預設值,我們建議在您專案的 prisma/
資料夾內編寫一個 seed 腳本,並使用以下命令啟動它。
- TypeScript
- JavaScript
"prisma": {
"seed": "ts-node prisma/seed.ts"
},
對於 TypeScript,ts-node
預設會進行轉譯和類型檢查;可以使用以下標誌 --transpile-only
停用類型檢查。
範例:"seed": "ts-node --transpile-only prisma/seed.ts"
這對於減少記憶體使用量 (RAM) 並提高 seed 腳本的執行速度很有用。
"prisma": {
"seed": "node prisma/seed.js"
},
Prisma Migrate 的整合資料填充
資料庫填充在 Prisma ORM 中以兩種方式發生:使用 prisma db seed
手動填充,以及在 prisma migrate reset
和(在某些情況下)prisma migrate dev
中自動填充。
使用 prisma db seed
,您 決定何時調用 seed 命令。例如,它對於測試設定或準備新的開發環境很有用。
Prisma Migrate 也與您的 seed 無縫整合,假設您遵循以下章節中的步驟。當 Prisma Migrate 重置開發資料庫時,會自動觸發資料填充。
Prisma Migrate 在以下情況下重置資料庫並觸發資料填充
- 您手動執行
prisma migrate reset
CLI 命令。 - 資料庫在使用
prisma migrate dev
的上下文中以互動方式重置 - 例如,由於遷移歷史衝突或資料庫 Schema 漂移。 - 資料庫實際上是由
prisma migrate dev
建立的,因為它之前不存在。
當您想要在不填充資料的情況下使用 prisma migrate dev
或 prisma migrate reset
時,您可以傳遞 --skip-seed
標誌。
範例 seed 腳本
在這裡,我們針對不同的情況建議一些特定的 seed 腳本。您可以自由地以任何方式自訂這些腳本,但也可以按此處呈現的方式使用它們
使用 TypeScript 或 JavaScript 填充您的資料庫
- TypeScript
- JavaScript
-
建立一個名為
seed.ts
的新檔案。它可以放置在您專案的資料夾結構中的任何位置。下面的範例將其放置在/prisma
資料夾中。 -
在
seed.ts
檔案中,匯入 Prisma Client,初始化它並建立一些記錄。作為範例,採用以下具有User
和Post
模型的 Prisma Schemaschema.prismamodel User {
id Int @id @default(autoincrement())
email String @unique
name String
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
content String
published Boolean
user User @relation(fields: [userId], references: [id])
userId Int
}在您的
seed.ts
檔案中建立一些新的使用者和文章seed.tsimport { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
async function main() {
const alice = await prisma.user.upsert({
where: { email: 'alice@prisma.io' },
update: {},
create: {
email: 'alice@prisma.io',
name: 'Alice',
posts: {
create: {
title: 'Check out Prisma with Next.js',
content: 'https://prisma.dev.org.tw/nextjs',
published: true,
},
},
},
})
const bob = await prisma.user.upsert({
where: { email: 'bob@prisma.io' },
update: {},
create: {
email: 'bob@prisma.io',
name: 'Bob',
posts: {
create: [
{
title: 'Follow Prisma on Twitter',
content: 'https://twitter.com/prisma',
published: true,
},
{
title: 'Follow Nexus on Twitter',
content: 'https://twitter.com/nexusgql',
published: true,
},
],
},
},
})
console.log({ alice, bob })
}
main()
.then(async () => {
await prisma.$disconnect()
})
.catch(async (e) => {
console.error(e)
await prisma.$disconnect()
process.exit(1)
}) -
新增
typescript
、ts-node
和@types/node
開發依賴項npm install -D typescript ts-node @types/node
-
將
prisma.seed
欄位新增到您的package.json
檔案package.json{
"name": "my-project",
"version": "1.0.0",
"prisma": {
"seed": "ts-node prisma/seed.ts"
},
"devDependencies": {
"@types/node": "^14.14.21",
"ts-node": "^9.1.1",
"typescript": "^4.1.3"
}
}某些專案可能需要您新增編譯選項。例如,當使用 Next.js 時,您將像這樣設定您的 seed 腳本
package.json"prisma": {
"seed": "ts-node --compiler-options {\"module\":\"CommonJS\"} prisma/seed.ts"
}, -
要填充資料庫,請執行
db seed
CLI 命令npx prisma db seed
-
建立一個名為
seed.js
的新檔案。它可以放置在您專案的資料夾結構中的任何位置。以下範例將其放置在/prisma
資料夾中。 -
在
seed.js
檔案中,匯入 Prisma Client,初始化它並建立一些記錄。作為範例,採用以下具有User
和Post
模型的 Prisma Schemaschema.prismagenerator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
title String
content String
published Boolean
user User @relation(fields: [userId], references: [id])
userId Int
}在您的
seed.js
檔案中建立一些新的使用者和文章seed.jsconst { PrismaClient } = require('@prisma/client')
const prisma = new PrismaClient()
async function main() {
const alice = await prisma.user.upsert({
where: { email: 'alice@prisma.io' },
update: {},
create: {
email: 'alice@prisma.io',
name: 'Alice',
posts: {
create: {
title: 'Check out Prisma with Next.js',
content: 'https://prisma.dev.org.tw/nextjs',
published: true,
},
},
},
})
const bob = await prisma.user.upsert({
where: { email: 'bob@prisma.io' },
update: {},
create: {
email: 'bob@prisma.io',
name: 'Bob',
posts: {
create: [
{
title: 'Follow Prisma on Twitter',
content: 'https://twitter.com/prisma',
published: true,
},
{
title: 'Follow Nexus on Twitter',
content: 'https://twitter.com/nexusgql',
published: true,
},
],
},
},
})
console.log({ alice, bob })
}
main()
.then(async () => {
await prisma.$disconnect()
})
.catch(async (e) => {
console.error(e)
await prisma.$disconnect()
process.exit(1)
}) -
將
prisma.seed
新增到您的package.json
檔案package.json{
"name": "my-project",
"version": "1.0.0",
"prisma": {
"seed": "node prisma/seed.js"
}
} -
要填充資料庫,請執行
db seed
CLI 命令npx prisma db seed
透過原始 SQL 查詢填充您的資料庫
您也可以使用原始 SQL 查詢來填充資料庫。
雖然您可以使用純文字 .sql
檔案(例如資料轉儲)來做到這一點,但如果這些原始查詢的體積很小,通常更容易將它們放入 seed.js
檔案中,因為這可以省去您處理資料庫連線字串的麻煩,並減少對 psql
等二進制檔案的依賴。
要將額外資料填充到上面的 schema.prisma
,請將以下內容新增到 seed.js
(或 seed.ts
)檔案中
async function rawSql() {
const result = await prisma.$executeRaw`INSERT INTO "User" ("id", "email", "name") VALUES (3, 'foo@example.com', 'Foo') ON CONFLICT DO NOTHING;`
console.log({ result })
}
並將此函數鏈接到 Promise 呼叫,例如對檔案末尾進行以下變更
main()
.then(rawSql)
.then(async () => {
await prisma.$disconnect()
})
.catch(async (e) => {
console.error(e)
await prisma.$disconnect()
process.exit(1)
})
透過任何語言(使用 Bash 腳本)填充您的資料庫
除了 TypeScript 和 JavaScript 之外,您也可以使用 Bash 腳本 (seed.sh
) 以另一種語言(例如 Go 或純 SQL)填充您的資料庫。
- Go
- SQL
以下範例在與 seed.sh
相同的資料夾中執行 Go 腳本
#!/bin/sh
# -e Exit immediately when a command returns a non-zero status.
# -x Print commands before they are executed
set -ex
# Seeding command
go run ./seed/
以下範例使用 psql 以在與 seed.sh
相同的資料夾中執行 SQL 腳本
#!/bin/sh
# -e Exit immediately when a command returns a non-zero status.
# -x Print commands before they are executed
set -ex
# Seeding command
psql file.sql
使用者定義的參數
此功能從 4.15.0 及更高版本開始提供。
prisma db seed
允許您在 seed 檔案中定義自訂參數,您可以將這些參數傳遞給 prisma db seed
命令。例如,您可以定義自己的參數,以便為不同的環境填充不同的資料,或在某些表格中部分填充資料。
以下是一個範例 seed 檔案,定義了一個自訂參數,以便在不同的環境中填充不同的資料
import { parseArgs } from 'node:util'
const options = {
environment: { type: 'string' },
}
async function main() {
const {
values: { environment },
} = parseArgs({ options })
switch (environment) {
case 'development':
/** data for your development */
break
case 'test':
/** data for your test environment */
break
default:
break
}
}
main()
.then(async () => {
await prisma.$disconnect()
})
.catch(async (e) => {
console.error(e)
await prisma.$disconnect()
process.exit(1)
})
然後,當使用 prisma db seed
時,您可以透過新增 分隔符號 — --
—,然後是您的自訂參數來提供 environment
參數
npx prisma db seed -- --environment development
更深入了解
以下是您可以與 Prisma ORM 整合在您的開發工作流程中以填充資料庫的其他工具的非詳盡列表