跳到主要内容

数据播种

本指南介绍了如何使用 Prisma Client 和 Prisma ORM 的集成数据播种功能来播种数据库。数据播种允许您一致地在数据库中重新创建相同的数据,并且可用于:

  • 用应用程序启动所需的数据填充数据库,例如默认语言或货币。
  • 为开发环境中的应用程序验证和使用提供基本数据。如果您正在使用 Prisma Migrate,这尤其有用,因为它有时需要重置您的开发数据库。

如何在 Prisma ORM 中播种数据库

Prisma ORM 的集成数据播种功能期望您的 package.json 文件中 "prisma" 键的 "seed" 键中有一个命令。这可以是任何命令,prisma db seed 将执行它。在本指南中,作为默认设置,我们建议在项目的 prisma/ 文件夹中编写播种脚本并使用该命令启动它。


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

信息

对于 TypeScript,ts-node 默认执行转译和类型检查;可以通过 --transpile-only 标志禁用类型检查。

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

这对于减少内存使用(RAM)和提高播种脚本的执行速度很有用。

与 Prisma Migrate 集成的数据播种

使用 Prisma ORM,数据库播种有两种方式:手动使用 prisma db seed,以及在 prisma migrate reset 和(在某些情况下)prisma migrate dev 中自动进行。

使用 prisma db seed决定何时调用播种命令。它对于测试设置或准备新的开发环境很有用,例如。

Prisma Migrate 也与您的播种无缝集成,前提是您遵循以下部分中的步骤。当 Prisma Migrate 重置开发数据库时,播种会自动触发。

Prisma Migrate 在以下场景中重置数据库并触发数据播种:

  • 您手动运行 prisma migrate reset CLI 命令。
  • 在使用 prisma migrate dev 的上下文中交互式地重置数据库——例如,由于迁移历史冲突或数据库 schema 漂移。
  • 数据库实际上是由 prisma migrate dev 创建的,因为它之前不存在。

当您希望在不播种的情况下使用 prisma migrate devprisma migrate reset 时,可以传递 --skip-seed 标志。

播种脚本示例

这里我们为不同情况提供了一些特定的播种脚本。您可以随意自定义它们,也可以按此处所示使用它们。

使用 TypeScript 或 JavaScript 播种数据库

  1. 创建一个名为 seed.ts 的新文件。它可以放在项目文件夹结构的任何位置。下面的示例将其放在 /prisma 文件夹中。

  2. seed.ts 文件中,导入 Prisma Client,初始化它并创建一些记录。例如,以下 Prisma schema 包含 UserPost 模型:

    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.org.cn/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 时,您会像这样设置您的播种脚本:

    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 允许您在播种文件中定义自定义参数,您可以将其传递给 prisma db 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 集成到开发工作流中以播种数据库的其他工具的非详尽列表:

© . All rights reserved.