数据库迁移 Database Migrations

Strapi 数据库迁移是修改数据库的方法

数据库迁移用于对数据库运行一次性查询,通常用于在升级 Strapi 应用程序时修改表结构或数据。这些迁移在应用程序启动时自动运行,并在 Strapi 在启动时执行的自动架构迁移之前执行。

🚧 实验性功能

数据库迁移是实验性的。此功能仍在进行中,将继续更新和改进。与此同时,请随时在 forum 或社区 Discord 上寻求帮助。

了解数据库迁移文件

迁移使用存储在 ./database/migrations 中的 JavaScript 迁移文件运行。

Strapi 会自动检测迁移文件并在下次启动时按字母顺序运行一次。每个新文件都执行一次。迁移在数据库表与内容类型架构同步之前运行。

  • 目前 Strapi 不支持向下迁移。这意味着如果您需要恢复迁移,则必须手动执行。计划在未来实现向下迁移,但目前没有可用的时间表。
  • Strapi 将在没有警告的情况下删除任何未知表。这意味着数据库迁移只能用于在更改 Strapi 架构时保留数据。forceMigrationrunMigrations 数据库配置参数 可用于微调数据库迁移行为。

迁移文件应导出函数 up(),该函数在升级时使用(例如添加新表 my_new_table)。

up() 函数在数据库事务中运行,这意味着如果在迁移期间查询失败,则整个迁移将被取消,并且不会对数据库应用任何更改。如果在迁移函数中创建了另一个事务,它将充当嵌套事务。

没有 CLI 可以手动执行数据库迁移。

创建迁移文件

要创建迁移文件:

  1. ./database/migrations 文件夹中,创建一个以迁移日期和名称命名的新文件(例如 2022.05.10T00.00.00.name-of-my-migration.js)。确保文件名遵循此命名模式,因为文件的字母顺序定义了迁移必须运行的顺序。
  2. 将以下模板复制并粘贴到之前创建的文件中:
jsx
'use strict'

async function up(knex) {}

module.exports = { up }
  1. 通过在 up() 函数中添加实际迁移代码来填充模板。 up() 接收一个已处于事务状态的 Knex 实例,可用于运行数据库查询。

迁移文件示例

./database/migrations/2022.05.10T00.00.00.name-of-my-migration.js
jsx
module.exports = {
  async up(knex) {
    // 您拥有对 Knex.js API 的完全访问权限,并且已初始化与数据库的连接

    // 示例:重命名表
    await knex.schema.renameTable('oldName', 'newName')

    // 示例:重命名列
    await knex.schema.table('someTable', (table) => {
      table.renameColumn('oldName', 'newName')
    })

    // 示例:更新数据
    await knex.from('someTable').update({ columnName: 'newValue' }).where({ columnName: 'oldValue' })
  },
}

使用用于迁移的 Strapi 实例

如果用户选择不直接使用 Knex 进行迁移,而是使用 Strapi 实例,则必须使用 strapi.db.transaction() 包装迁移代码。如果不这样做,如果发生错误,可能会导致迁移无法回滚。

带有 Strapi 实例的迁移文件示例

./database/migrations/2022.05.10T00.00.00.name-of-my-migration.js
jsx
module.exports = {
  async up() {
    await strapi.db.transaction(async () => {
      // 您的迁移代码在此

      // 示例:创建新条目
      await strapi.entityService.create('api::article.article', {
        data: {
          title: 'My Article',
        },
      })

      // 示例:自定义服务方法
      await strapi.service('api::article.article').updateRelatedArticles()
    })
  },
}