播种
本指南介绍了如何使用 Prisma Client 和 Prisma ORM 的集成数据库填充功能来填充数据库。数据库填充允许您持续地在数据库中重新创建相同的数据,并可用于:
- 使用应用程序启动所需的数据(例如默认语言或货币)填充数据库。
- 提供基本数据,用于在开发环境中验证和使用应用程序。如果您正在使用 Prisma Migrate,这尤其有用,因为 Prisma Migrate 有时需要重置您的开发数据库。
如何在 Prisma ORM 中填充数据库
Prisma ORM 的集成填充功能期望在您的 prisma.config.ts 文件的 migrations 对象中的 "seed" 键中有一个命令。这可以是任何命令,prisma db seed 将只执行它。在本指南中,作为默认设置,我们建议在您项目的 prisma/ 文件夹中编写一个填充脚本,并使用该命令启动它。
import 'dotenv/config'
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
seed: "tsx prisma/seed.ts"
},
datasource: {
url: env("DATABASE_URL"),
},
});
使用 Prisma Migrate 进行集成填充
当您运行 prisma db seed 时,会发生数据库填充。使用 prisma db seed,您决定何时调用填充命令。例如,它对于测试设置或准备新的开发环境可能很有用。
仅限 Prisma 6
Prisma Migrate 也与您的填充无缝集成,前提是您遵循以下部分中的步骤。当 Prisma Migrate 重置开发数据库时,填充会自动触发。
Prisma Migrate 在以下情况下重置数据库并触发填充:
- 您手动运行
prisma migrate resetCLI 命令。 - 在使用
prisma migrate dev的上下文中以交互方式重置数据库 — 例如,由于迁移历史冲突或数据库 schema 漂移。 - 数据库实际上是由
prisma migrate dev创建的,因为它以前不存在。
当您想在不填充的情况下使用 prisma migrate dev 或 prisma migrate reset 时,您可以传递 --skip-seed 标志。
示例填充脚本
我们在此处为不同情况提供了一些特定的填充脚本。您可以自由地以任何方式自定义它们,也可以按此处所示使用它们
使用 TypeScript 或 JavaScript 填充数据库
- TypeScript
- JavaScript
-
创建一个名为
seed.ts的新文件。它可以放在项目文件夹结构中的任何位置。下面的示例将其放在/prisma文件夹中。 -
在
seed.ts文件中,导入 Prisma Client,初始化它并创建一些记录。例如,采用以下带有User和Post模型的 Prisma schema:schema.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/generated/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)
}) -
添加
typescript、tsx和@types/node开发依赖项npm install -D typescript tsx @types/node -
将
seed字段添加到您的prisma.config.ts文件中prisma.config.tsimport 'dotenv/config'
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
seed: "tsx prisma/seed.ts"
},
datasource: {
url: env("DATABASE_URL"),
},
}); -
要填充数据库,请运行
db seedCLI 命令npx prisma db seed
-
创建一个名为
seed.js的新文件。它可以放在项目文件夹结构中的任何位置。以下示例将其放在/prisma文件夹中。 -
在
seed.js文件中,导入 Prisma Client,初始化它并创建一些记录。例如,采用以下带有User和Post模型的 Prisma schema:schema.prismagenerator client {
provider = "prisma-client"
output = "./generated"
}
datasource db {
provider = "postgresql"
}
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.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)
}) -
将
seed字段添加到您的prisma.config.ts文件中prisma.config.tsimport 'dotenv/config'
import { defineConfig, env } from "prisma/config";
export default defineConfig({
schema: "prisma/schema.prisma",
migrations: {
path: "prisma/migrations",
seed: "node prisma/seed.js"
},
datasource: {
url: env("DATABASE_URL"),
},
}); -
要填充数据库,请运行
db seedCLI 命令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 允许您在填充文件中定义自定义参数,您可以将这些参数传递给 prisma db 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 集成以在开发工作流程中填充数据库的其他工具的非详尽列表