使用扩展和收缩模式迁移数据
10 分钟
介绍
在生产环境中更改数据库模式时,确保数据一致性并避免停机至关重要。本指南将向您展示如何使用“扩展和收缩”模式安全地迁移列之间的数据。我们将通过一个实际示例,演示如何用枚举字段替换布尔字段,同时保留现有数据。
先决条件
在开始本指南之前,请确保您已具备以下条件:
- 已安装 Node.js(版本 18 或更高版本)
- 一个具有现有模式的 Prisma ORM 项目
- 支持的数据库(PostgreSQL、MySQL、SQLite、SQL Server 等)
- 访问开发和生产数据库
- 对 Git 分支的基本理解
- 对 TypeScript 的基本熟悉
1. 设置您的环境
1.1. 查看初始模式
从包含 Post 模型的初始模式开始
generator client {
provider = "prisma-client"
output = "./generated/prisma"
}
datasource db {
provider = "postgresql"
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
}
1.2. 配置 Prisma
在项目根目录中创建一个 prisma.config.ts 文件,内容如下
prisma.config.ts
import 'dotenv/config'
import { defineConfig, env } from 'prisma/config';
export default defineConfig({
schema: 'prisma/schema.prisma',
migrations: {
path: 'prisma/migrations',
},
datasource: {
url: env('DATABASE_URL'),
},
});
注意
您需要安装所需的软件包。如果您还没有安装,请使用您的包管理器安装它们
npm install prisma @types/pg --save-dev
npm install @prisma/client @prisma/adapter-pg pg dotenv
信息
如果你使用的是其他数据库提供程序(MySQL、SQL Server、SQLite),请安装相应的驱动程序适配器包,而不是 @prisma/adapter-pg。有关更多信息,请参阅 数据库驱动程序。
:::
1.3. 创建开发分支
为您的更改创建一个新分支
git checkout -b create-status-field
2. 扩展模式
2.1. 添加新列
更新您的模式以添加新的 Status 枚举和字段
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean? @default(false)
status Status @default(Unknown)
}
enum Status {
Unknown
Draft
InProgress
InReview
Published
}
2.2. 创建迁移
生成迁移
npx prisma migrate dev --name add-status-column
然后生成 Prisma Client
npx prisma generate
3. 迁移数据
3.1. 创建迁移脚本
为数据迁移创建一个新的 TypeScript 文件
import { PrismaClient } from '../generated/prisma/client'
import { PrismaPg } from '@prisma/adapter-pg'
import 'dotenv/config'
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL,
})
const prisma = new PrismaClient({
adapter,
})
async function main() {
await prisma.$transaction(async (tx) => {
const posts = await tx.post.findMany()
for (const post of posts) {
await tx.post.update({
where: { id: post.id },
data: {
status: post.published ? 'Published' : 'Unknown',
},
})
}
})
}
main()
.catch(async (e) => {
console.error(e)
process.exit(1)
})
.finally(async () => await prisma.$disconnect())
3.2. 设置迁移脚本
将迁移脚本添加到您的 package.json 中
{
"scripts": {
"data-migration:add-status-column": "tsx ./prisma/migrations/<migration-timestamp>/data-migration.ts"
}
}
3.3. 执行迁移
- 更新您的 DATABASE_URL 以指向生产数据库
- 运行迁移脚本
npm run data-migration:add-status-column
4. 收缩模式
4.1. 创建清理分支
创建一个新分支来删除旧列
git checkout -b drop-published-column
4.2. 删除旧列
更新您的模式以删除 published 字段
model Post {
id Int @id @default(autoincrement())
title String
content String?
status Status @default(Unknown)
}
enum Status {
Draft
InProgress
InReview
Published
}
4.3. 生成清理迁移
创建并运行最终迁移
npx prisma migrate dev --name drop-published-column
然后生成 Prisma Client
npx prisma generate
5. 部署到生产环境
5.1. 设置部署
将以下命令添加到您的 CI/CD 管道中
npx prisma migrate deploy
5.2. 监控部署
部署后,查看日志中的任何错误并监控应用程序的行为。
故障排除
常见问题和解决方案
-
因缺少默认值导致迁移失败
- 确保您已添加适当的默认值
- 检查所有现有记录是否可以迁移
-
数据丢失预防
- 在运行迁移之前,请务必备份您的数据库
- 首先在生产数据的副本上测试迁移
-
事务回滚
- 如果数据迁移失败,事务将自动回滚
- 修复任何错误并重试迁移
后续步骤
现在您已经完成了第一次扩展和收缩迁移,您可以
- 了解更多关于Prisma Migrate的信息
- 探索模式原型设计
- 理解自定义迁移
更多信息
与 Prisma 保持联系
通过以下方式与我们保持联系,继续你的 Prisma 之旅: 我们的活跃社区。保持信息灵通,参与其中,并与其他开发人员协作。
- 在 X 上关注我们 获取公告、直播活动和实用技巧。
- 加入我们的 Discord 提问、与社区交流,并通过对话获得积极支持。
- 在 YouTube 上订阅 获取教程、演示和直播。
- 在 GitHub 上参与 加星收藏存储库、报告问题或为问题做出贡献。