原型化您的 schema
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-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
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 push
db 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-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
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-tags
Prisma 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
标志来忽略种子脚本。
此时,您的原型设计的最终结果将保留在迁移中,并可以推送到其他环境(测试、生产或您的团队其他成员)。