原型化你的 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 更改导致 seed 脚本不再起作用,可以使用 --skip-seed
标志忽略 seed 脚本。
此时,原型化的最终结果已保存在迁移中,可以推送到其他环境(测试、生产或团队的其他成员)。