原型化您的模式
Prisma CLI 有一个专门用于原型化 schema 的命令:db push
db push 使用与 Prisma Migrate 相同的引擎来同步你的 Prisma schema 与你的数据库 schema。db push 命令会
-
内省数据库以推断并执行所需的更改,使你的数据库 schema 反映你的 Prisma schema 的状态。
-
默认情况下,在更改应用于数据库 schema 后,会触发生成器(例如 Prisma Client)。你无需手动调用
prisma generate。 -
如果
db push预计更改可能导致数据丢失,它会- 抛出错误
- 如果你仍然希望进行更改,则需要
--accept-data-loss选项
备注:
选择 db push 还是 Prisma Migrate
db push 在以下情况下效果良好:
- 你希望在本地快速原型和迭代 schema 设计,而无需将这些更改部署到其他环境,例如其他开发人员、暂存和生产环境。
- 你优先考虑达到一个期望的最终状态,而不是达到该最终状态所执行的更改或步骤(无法预览
db push所做的更改) - 你不需要控制 schema 更改如何影响数据。无法编排 schema 和数据迁移——如果
db push预计更改将导致数据丢失,你可以使用--accept-data-loss选项接受数据丢失或停止该过程。无法自定义这些更改。
请参阅使用 db push 进行 Schema 原型化以获取如何以这种方式使用 db push 的示例。
在以下情况下不推荐使用 db push:
- 你希望在不丢失数据的情况下将 schema 更改复制到其他环境。你可以使用
db push进行原型化,但你应该使用迁移来提交 schema 更改并将其应用于其他环境。 - 你希望对 schema 更改的执行方式进行细粒度控制——例如,重命名列而不是删除它并创建新列。
- 你希望跟踪数据库 schema 随时间变化的更改。
db push不会创建任何允许你跟踪这些更改的工件。 - 你希望 schema 更改是可逆的。你可以再次使用
db push恢复到原始状态,但这可能会导致数据丢失。
我可以同时使用 Prisma Migrate 和 db push 吗?
是的,你可以在开发工作流程中同时使用 db push 和 Prisma Migrate。例如,你可以
- 在项目开始时使用
db push原型化 schema,并在对初稿满意时初始化迁移历史记录 - 使用
db push原型化对现有 schema 的更改,然后运行prisma migrate dev从你的更改生成迁移(系统会要求你重置)
原型化新 Schema
以下场景演示了如何使用 db push 将新 schema 与空数据库同步,并演进该 schema——包括当 db push 检测到更改将导致数据丢失时会发生什么。
-
创建 schema 的初稿
generator client {
provider = "prisma-client"
output = "./generated"
}
datasource db {
provider = "postgresql"
}
model User {
id Int @id @default(autoincrement())
name String
jobTitle String
posts Post[]
profile Profile?
}
model Profile {
id Int @id @default(autoincrement())
biograpy String // Intentional typo!
userId Int @unique
user User @relation(fields: [userId], references: [id])
}
model Post {
id Int @id @default(autoincrement())
title String
published Boolean @default(true)
content String @db.VarChar(500)
authorId Int
author User @relation(fields: [authorId], references: [id])
categories Category[]
}
model Category {
id Int @id @default(autoincrement())
name String @db.VarChar(50)
posts Post[]
@@unique([name])
} -
使用
db push将初始 schema 推送到数据库npx prisma db push -
创建一些示例内容
const add = await prisma.user.create({
data: {
name: 'Eloise',
jobTitle: 'Programmer',
posts: {
create: {
title: 'How to create a MySQL database',
content: 'Some content',
},
},
},
}) -
进行添加性更改——例如,创建一个新的必填字段
// ... //
model Post {
id Int @id @default(autoincrement())
title String
description String
published Boolean @default(true)
content String @db.VarChar(500)
authorId Int
author User @relation(fields: [authorId], references: [id])
categories Category[]
}
// ... // -
推送更改
npx prisma db pushdb push将失败,因为除非你提供默认值,否则无法向具有现有内容的表添加必填字段。 -
重置数据库中的所有数据并重新应用迁移。
npx prisma migrate reset注意:与 Prisma Migrate 不同,
db push不会生成你可以修改以保留数据的迁移,因此最适合在开发环境中进行原型化。 -
继续演进你的 schema,直到它达到相对稳定的状态。
-
初始化迁移历史记录
npx prisma migrate dev --name initial-state达到初始原型所采取的步骤不会被保留——
db push不会生成历史记录。 -
将你的迁移历史记录和 Prisma schema 推送到源代码管理(例如 Git)。
此时,你的原型设计的最终草案已保存在迁移中,可以推送到其他环境(测试、生产或团队的其他成员)。
使用现有迁移历史记录进行原型化
以下场景演示了如何使用 db push 原型化对已存在迁移历史记录的 Prisma schema 的更改。
-
检查最新的 Prisma schema 和迁移历史记录
generator client {
provider = "prisma-client"
output = "./generated"
}
datasource db {
provider = "postgresql"
}
model User {
id Int @id @default(autoincrement())
name String
jobTitle String
posts Post[]
profile Profile?
}
model Profile {
id Int @id @default(autoincrement())
biograpy String // Intentional typo!
userId Int @unique
user User @relation(fields: [userId], references: [id])
}
model Post {
id Int @id @default(autoincrement())
title String
published Boolean @default(true)
content String @db.VarChar(500)
authorId Int
author User @relation(fields: [authorId], references: [id])
categories Category[]
}
model Category {
id Int @id @default(autoincrement())
name String @db.VarChar(50)
posts Post[]
@@unique([name])
} -
原型化你的新功能,这可能涉及任意数量的步骤。例如,你可能
- 创建一个
tags String[]字段,然后运行db push - 将字段类型更改为
tags Tag[]并添加一个名为Tag的新模型,然后运行db push - 改变主意并恢复原始
tags String[]字段,然后调用db push - 手动更改数据库中的
tags字段——例如,添加约束
经过多次尝试后,最终的 schema 更改如下所示
model Post {
id Int @id @default(autoincrement())
title String
description String
published Boolean @default(true)
content String @db.VarChar(500)
authorId Int
author User @relation(fields: [authorId], references: [id])
categories Category[]
tags String[]
} - 创建一个
-
要创建添加新
tags字段的迁移,请运行migrate dev命令npx prisma migrate dev --name added-tagsPrisma Migrate 会提示你重置,因为你在原型化期间手动和使用
db push所做的更改不属于迁移历史记录√ Drift detected: Your database schema is not in sync with your migration history.
We need to reset the PostgreSQL database "prototyping" at "localhost:5432".警告这将导致数据完全丢失。
npx prisma migrate reset -
Prisma Migrate 会重放现有的迁移历史记录,根据你的 schema 更改生成新的迁移,并将这些更改应用于数据库。
使用 migrate dev 时,如果你的 schema 更改意味着种子脚本将不再起作用,你可以使用 --skip-seed 标志来忽略种子脚本。
此时,你的原型设计的最终结果已保存在迁移中,可以推送到其他环境(测试、生产或团队的其他成员)。