跳到主要內容

資料填充 (Seeding)

本指南說明如何使用 Prisma Client 和 Prisma ORM 整合的資料填充功能來填充您的資料庫。資料填充讓您可以一致地重新建立資料庫中的相同資料,並且可以用於

  • 使用應用程式啟動所需的資料(例如預設語言或貨幣)來填充您的資料庫。
  • 為在開發環境中驗證和使用您的應用程式提供基本資料。如果您正在使用 Prisma Migrate,而有時需要重置您的開發資料庫,這特別有用。

如何在 Prisma ORM 中填充您的資料庫

Prisma ORM 整合的資料填充功能預期在您 package.json 檔案的 "prisma" 鍵中的 "seed" 鍵中有一個命令。這可以是任何命令,prisma db seed 只會執行它。在本指南中以及作為預設值,我們建議在您專案的 prisma/ 資料夾內編寫一個 seed 腳本,並使用以下命令啟動它。


"prisma": {
"seed": "ts-node prisma/seed.ts"
},

資訊

對於 TypeScript,ts-node 預設會進行轉譯和類型檢查;可以使用以下標誌 --transpile-only 停用類型檢查。

範例:"seed": "ts-node --transpile-only prisma/seed.ts"

這對於減少記憶體使用量 (RAM) 並提高 seed 腳本的執行速度很有用。

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 devprisma migrate reset 時,您可以傳遞 --skip-seed 標誌。

範例 seed 腳本

在這裡,我們針對不同的情況建議一些特定的 seed 腳本。您可以自由地以任何方式自訂這些腳本,但也可以按此處呈現的方式使用它們

使用 TypeScript 或 JavaScript 填充您的資料庫

  1. 建立一個名為 seed.ts 的新檔案。它可以放置在您專案的資料夾結構中的任何位置。下面的範例將其放置在 /prisma 資料夾中。

  2. seed.ts 檔案中,匯入 Prisma Client,初始化它並建立一些記錄。作為範例,採用以下具有 UserPost 模型的 Prisma Schema

    schema.prisma
    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.ts 檔案中建立一些新的使用者和文章

    seed.ts
    import { 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)
    })
  3. 新增 typescriptts-node@types/node 開發依賴項

    npm install -D typescript ts-node @types/node
  1. 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"
    },
  2. 要填充資料庫,請執行 db seed CLI 命令

    npx prisma db seed

透過原始 SQL 查詢填充您的資料庫

您也可以使用原始 SQL 查詢來填充資料庫。

雖然您可以使用純文字 .sql 檔案(例如資料轉儲)來做到這一點,但如果這些原始查詢的體積很小,通常更容易將它們放入 seed.js 檔案中,因為這可以省去您處理資料庫連線字串的麻煩,並減少對 psql 等二進制檔案的依賴。

要將額外資料填充到上面的 schema.prisma,請將以下內容新增到 seed.js(或 seed.ts)檔案中

seed.js
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 呼叫,例如對檔案末尾進行以下變更

seed.js
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)填充您的資料庫。


以下範例在與 seed.sh 相同的資料夾中執行 Go 腳本


seed.sh
#!/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/

使用者定義的參數

此功能從 4.15.0 及更高版本開始提供。

prisma db seed 允許您在 seed 檔案中定義自訂參數,您可以將這些參數傳遞給 prisma db seed 命令。例如,您可以定義自己的參數,以便為不同的環境填充不同的資料,或在某些表格中部分填充資料。

以下是一個範例 seed 檔案,定義了一個自訂參數,以便在不同的環境中填充不同的資料

"seed.js"
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 整合在您的開發工作流程中以填充資料庫的其他工具的非詳盡列表