跳至主要内容

心智模型

本指南提供了在使用关系数据库时使用 Prisma Migrate 进行数据库迁移的概念性概述。它涵盖:什么是数据库迁移,它们的价值,以及什么是 Prisma Migrate 以及如何在不同环境中使用 Prisma Migrate 演变数据库模式。

如果您正在使用 MongoDB,请使用 prisma db push 来演变您的模式。

什么是数据库迁移?

数据库迁移是一组受控的更改,用于修改和演变数据库模式的结构。 迁移帮助您将数据库模式从一种状态转换为另一种状态。 例如,在迁移中,您可以创建或删除表和列,拆分表中的字段,或将类型和约束添加到数据库。

用于演变数据库模式的模式

本节介绍用于演变数据库模式的通用模式迁移模式。

两种主要的模式迁移模式是

  • 模型/实体优先迁移: 使用这种模式,您可以使用代码定义数据库模式的结构,然后使用迁移工具生成 SQL,例如,用于同步您的应用程序和数据库模式。

Model-first migration flow

  • 数据库优先迁移: 使用这种模式,您定义数据库的结构,并使用 SQL 将其应用于数据库。 然后,您内省数据库以生成代码,该代码描述数据库的结构,以同步您的应用程序和数据库模式。

Database-first migration flow

信息

注意

为简单起见,我们选择上述术语来描述演变数据库模式的不同模式。 其他工具和库可能会使用不同的术语来描述不同的模式。

迁移文件 (SQL) 理想情况下应与应用程序代码一起存储。 它们也应该在版本控制中进行跟踪,并与从事应用程序的其他团队成员共享。

迁移提供状态管理,这有助于您跟踪数据库的状态。

迁移还允许您复制数据库在特定时间点的状态,这在与其他团队成员协作时非常有用,例如,在不同的分支之间切换。

有关数据库迁移的更多信息,请参阅 Prisma Data Guide

什么是 Prisma Migrate?

Prisma Migrate 是一个数据库迁移工具,它支持模型/实体优先迁移模式来管理本地环境和生产环境中的数据库模式。

在项目中使用 Prisma Migrate 时,工作流程将是迭代的,如下所示

本地开发环境(功能分支)

  1. 演变你的 Prisma 模式
  2. 使用 prisma migrate devprisma db push 将你的 Prisma 模式与本地开发数据库的数据库模式同步

预览/暂存环境(功能拉取请求)

  1. 将你的更改推送到功能拉取请求
  2. 使用 CI 系统(例如 GitHub Actions)使用 prisma migrate deploy 将你的 Prisma 模式和迁移历史与你的预览数据库同步

生产环境(主分支)

  1. 将你的应用程序代码从功能分支合并到你的主分支
  2. 使用 CI 系统(例如 GitHub Actions)使用 prisma migrate deploy 将你的 Prisma 模式和迁移历史与你的生产数据库同步

Prisma Migrate workflow

Prisma Migrate 如何跟踪迁移状态

Prisma Migrate 使用以下状态来跟踪你的数据库模式的状态

  • Prisma 模式:你的真实来源,用于定义数据库模式的结构。
  • 迁移历史:你的 prisma/migrations 文件夹中的 SQL 文件,表示对你的数据库模式所做的更改的历史记录。
  • 迁移表:数据库中的 prisma_migrations 表,用于存储已应用于数据库的迁移的元数据。
  • 数据库模式:数据库的状态。

Prisma Migrate "state management"

使用 Prisma Migrate 时的要求

  • 理想情况下,你应该为每个环境使用一个数据库。 例如,你可能为开发、预览和生产环境分别拥有一个单独的数据库。
  • 你在开发环境中使用的数据库是可处置的 — 你可以根据需要在创建、使用和删除数据库。
  • 每个环境中使用的数据库配置应该一致。 这对于确保跨工作流程移动的特定迁移对数据库产生相同的更改非常重要。
  • Prisma 模式作为真实来源 — 描述你的 数据库模式的形状。

使用 Prisma Migrate 演变你的数据库模式

本节介绍如何使用 Prisma Migrate 在不同的环境(开发、暂存和生产)中演变你的数据库模式。

开发环境 (本地) 中的 Prisma Migrate

使用 prisma migrate dev 跟踪你的迁移历史

prisma migrate dev 命令允许你跟踪对数据库所做的更改。 prisma migrate dev 命令会自动生成 SQL 迁移文件(保存在 /prisma/migrations 中)并将其应用于数据库。 当迁移应用于数据库时,你的数据库中的迁移表 (_prisma_migrations) 也会更新。

Prisma Migrate dev flow

prisma migrate dev 命令使用以下状态来跟踪数据库的状态

  • Prisma 模式
  • 迁移历史
  • 迁移表
  • 数据库模式

注意:用于跟踪迁移状态的状态与 Prisma Migrate 如何跟踪迁移状态 部分中描述的状态相同。

你可以在将迁移应用于数据库之前使用 --create-only 标志对其进行自定义。 例如,如果你想在不造成任何数据丢失的情况下重命名列,或者加载数据库扩展(在 PostgreSQL 中)和数据库视图(当前不支持),你可能想要编辑迁移。

在幕后,Prisma Migrate 使用 影子数据库来检测 模式偏移并生成新的迁移。

注意prisma migrate dev 仅用于开发环境中,并且使用可处置的数据库。

如果 prisma migrate dev 检测到模式偏移或迁移历史冲突,系统会提示你重置(删除并重新创建你的数据库)你的数据库,以同步迁移历史和数据库模式。

展开以查看使用卡通解释的影子数据库

A cartoon that shows how the shadow database works.

解决模式偏移

当预期的数据库模式与迁移历史中存在的模式不同时,会发生模式偏移。 例如,当你手动更新数据库模式,而没有相应地更新 Prisma 模式和 prisma/migrations 时,可能会发生这种情况。

对于这种情况,你可以使用 prisma migrate diff 命令来比较你的迁移历史,并还原对数据库模式所做的更改。

Revert database schema with migrate diff

你可以使用 migrate diff 来生成 SQL 代码,该代码可以:

  • 还原数据库 schema 中所做的更改,使其与当前的 Prisma schema 同步
  • 将数据库 schema 向前推进,以应用 Prisma schema 和 /migrations 中缺失的更改

然后,你可以使用 prisma db execute 命令将更改应用到你的数据库。

原型化你的 schema

prisma db push 命令允许你同步 Prisma schema 和数据库 schema,而无需持久化迁移 (/prisma/migrations)。prisma db push 命令使用以下状态来跟踪数据库的状态:

  • Prisma 模式
  • 数据库模式

prisma db push development flow

在以下情况下,prisma db push 命令很有用:

  • 你希望在本地快速原型化和迭代 schema 设计,而无需将这些更改部署到其他环境,例如其他开发者、暂存环境和生产环境。
  • 你优先考虑达到期望的最终状态,而不是达到该最终状态所执行的更改或步骤(无法预览 prisma db push 所做的更改)。
  • 你不需要控制 schema 更改如何影响数据。没有办法协调 schema 和数据迁移 - 如果 prisma db push 预计更改会导致数据丢失,你可以选择使用 --accept-data-loss 选项接受数据丢失,或者停止该过程 - 没有办法自定义更改。

如果 prisma db push 命令检测到对数据库 schema 的破坏性更改,它将提示你重置数据库。例如,当你在包含现有内容的表中添加一个必需字段,但未提供默认值时,就会发生这种情况。

当你的数据库 schema 与迁移历史记录和迁移表不同步时,就会发生schema 漂移

在暂存和生产环境中使用 Prisma Migrate

同步你的迁移历史记录

prisma migrate deploy 命令允许你将开发环境中的迁移历史记录与暂存或生产环境中的数据库同步。

在底层,migrate deploy 命令会:

  1. 比较已应用的迁移(捕获的 _prisma_migrations)和迁移历史记录 (/prisma/migrations)
  2. 应用待处理的迁移
  3. 使用新的迁移更新 _prisma_migrations

Workflow of Prisma Migrate

该命令应在自动化的 CI/CD 环境中运行,例如 GitHub Actions。

如果你没有迁移历史记录 (/migrations),即使用 prisma db push,你将不得不在暂存和生产环境继续使用 prisma db push。请注意应用于数据库 schema 的更改,因为其中一些更改可能具有破坏性。例如,prisma db push 无法判断你何时执行列重命名。它将提示数据库重置(删除并重新创建)。