Skip to main content

播种

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

¥This guide describes how to seed your database using Prisma Client and Prisma ORM's integrated seeding functionality. Seeding allows you to consistently re-create the same data in your database and can be used to:

  • 使用应用启动所需的数据填充数据库,例如默认语言或货币。

    ¥Populate your database with data that is required for your application to start, such as a default language or currency.

  • 提供用于在开发环境中验证和使用你的应用的基本数据。如果你使用 Prisma Migrate,这尤其有用,有时需要重置开发数据库。

    ¥Provide basic data for validating and using your application in a development environment. This is particularly useful if you are using Prisma Migrate, which sometimes requires resetting your development database.

如何在 Prisma ORM 中为数据库播种

¥How to seed your database in Prisma ORM

Prisma ORM 的集成播种功能需要 package.json 文件的 "prisma" 键中的 "seed" 键中的命令。这可以是任何命令,prisma db seed 将执行它。在本指南中,作为默认情况,我们建议在项目的 prisma/ 文件夹中编写种子脚本并使用命令启动它。

¥Prisma ORM's integrated seeding functionality expects a command in the "seed" key in the "prisma" key of your package.json file. This can be any command, prisma db seed will just execute it. In this guide and as a default, we recommend writing a seed script inside your project's prisma/ folder and starting it with the command.


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

info

With TypeScript,ts-node does transpiling and typechecking by default; typechecking can be disabled with the following flag --transpile-only.

Example: "seed": "ts-node --transpile-only prisma/seed.ts"

This can be useful to reduce memory usage (RAM) and increase execution speed of the seed script.

与 Prisma Migrate 集成播种

¥Integrated seeding with Prisma Migrate

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

¥Database seeding happens in two ways with Prisma ORM: manually with prisma db seed and automatically in prisma migrate reset and (in some scenarios) prisma migrate dev.

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

¥With prisma db seed, you decide when to invoke the seed command. It can be useful for a test setup or to prepare a new development environment, for example.

假设你按照以下部分中的步骤操作,Prisma Migrate 还可以与你的种子无缝集成。当 Prisma Migrate 重置开发数据库时,会自动触发播种。

¥Prisma Migrate also integrates seamlessly with your seeds, assuming you follow the steps in the section below. Seeding is triggered automatically when Prisma Migrate resets the development database.

Prisma Migrate 在以下情况下会重置数据库并触发播种:

¥Prisma Migrate resets the database and triggers seeding in the following scenarios:

  • 你手动运行 prisma migrate reset CLI 命令。

    ¥You manually run the prisma migrate reset CLI command.

  • 在使用 prisma migrate dev 的上下文中交互式重置数据库 - 例如,由于迁移历史冲突或数据库架构漂移。

    ¥The database is reset interactively in the context of using prisma migrate dev - for example, as a result of migration history conflicts or database schema drift.

  • 数据库实际上是由 prisma migrate dev 创建的,因为它之前不存在。

    ¥The database is actually created by prisma migrate dev, because it did not exist before.

当你想要使用 prisma migrate devprisma migrate reset 而不进行播种时,你可以传递 --skip-seed 标志。

¥When you want to use prisma migrate dev or prisma migrate reset without seeding, you can pass the --skip-seed flag.

示例种子脚本

¥Example seed scripts

这里我们针对不同情况推荐一些特定的种子脚本。你可以以任何方式自由自定义它们,但也可以按此处所示使用它们:

¥Here we suggest some specific seed scripts for different situations. You are free to customize these in any way, but can also use them as presented here:

使用 TypeScript 或 JavaScript 为数据库播种

¥Seeding your database with TypeScript or JavaScript

  1. Create a new file named seed.ts. This can be placed anywhere within your project's folder structure. The example below places it in the /prisma folder.

  2. In the seed.ts file, import Prisma Client, initialize it and create some records. As an example, take the following Prisma schema with a User and Post model:

    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
    }

    Create some new users and posts in your seed.ts file:

    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://www.prisma.io/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. Add typescript, ts-node and @types/node development dependencies:

    npm install -D typescript ts-node @types/node
  1. Add the prisma.seed field to your package.json file:

    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"
    }
    }

    Some projects may require you to add compile options. When using Next.js for example, you would setup your seed script like so:

    package.json
    "prisma": {
    "seed": "ts-node --compiler-options {\"module\":\"CommonJS\"} prisma/seed.ts"
    },
  2. To seed the database, run the db seed CLI command:

    npx prisma db seed

通过原始 SQL 查询为数据库播种

¥Seeding your database via raw SQL queries

你还可以使用原始 SQL 查询来为数据库添加数据。

¥You can also make use of raw SQL queries in order to seed the database with data.

虽然你可以为此使用纯文本 .sql 文件(例如数据转储),但将这些原始查询(如果它们的大小较短)放入 seed.js 文件中通常会更容易,因为它可以省去你工作的麻烦 输出数据库连接字符串并创建对像 psql 这样的二进制文件的依赖。

¥While you can use a plain-text .sql file (such as a data dump) for that, it is often easier to place those raw queries, if they're of short size, into the seed.js file because it saves you the hassle of working out database connection strings and creating a dependency on a binary like psql.

要将附加数据播种到上面的 schema.prisma,请将以下内容添加到 seed.js(或 seed.ts)文件:

¥To seed additional data to the schema.prisma above, add the following to the seed.js (or seed.ts) file:

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 调用,例如在文件末尾进行以下更改:

¥and chain this function to the promise calls, such as the following change towards the end of the file:

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

通过任何语言(使用 Bash 脚本)为数据库播种

¥Seeding your database via any language (with a Bash script)

除了 TypeScript 和 JavaScript 之外,你还可以使用 Bash 脚本 (seed.sh) 以另一种语言(例如 Go 或纯 SQL)为数据库播种。

¥In addition to TypeScript and JavaScript, you can also use a Bash script (seed.sh) to seed your database in another language such as Go, or plain SQL.


The following example runs a Go script in the same folder as seed.sh:


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/

用户定义的参数

¥User-defined arguments

此功能从版本 4.15.0 及更高版本可用。

¥This feature is available from version 4.15.0 and later.

prisma db seed 允许你在种子文件中定义自定义参数,你可以将其传递给 prisma db seed 命令。例如,你可以定义自己的参数来为不同环境播种不同的数据,或者在某些表中部分播种数据。

¥prisma db seed allows you to define custom arguments in your seed file that you can pass to the prisma db seed command. For example, you could define your own arguments to seed different data for different environments or partially seeding data in some tables.

以下是一个示例种子文件,它定义了一个自定义参数以在不同环境中播种不同的数据:

¥Here is an example seed file that defines a custom argument to seed different data in different environments:

"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 时通过添加 delimiter-- — 来提供 environment 参数,后跟你的自定义参数:

¥You can then provide the environment argument when using prisma db seed by adding a delimiter-- —, followed by your custom arguments:

npx prisma db seed -- --environment development

更进一步

¥Going further

以下是你可以在开发工作流程中与 Prisma ORM 集成以播种数据库的其他工具的非详尽列表:

¥Here's a non-exhaustive list of other tools you can integrate with Prisma ORM in your development workflow to seed your database: