patricknelson / silverstripe-migrations
SilverStripe 数据库迁移模块。简化 SilverStripe 3.x 的原子数据库迁移
Requires
- silverstripe/cms: ^3.0.0
- silverstripe/framework: ^3.0.0
README
简化 SilverStripe 3.x 的原子数据库迁移。受 Laravel 迁移功能的启发,这个相对简单的模块被构建为 SilverStripe 中已广泛使用的现有 dev/build
功能的增强。
SilverStripe 的数据库模式是 声明式的,这意味着代码定义了数据库 当前应该是怎样的状态,因此系统将执行所需操作以将当前模式更改为在任何给定时刻所声明的结构(通过 dev/build
代理)。相比之下,数据库迁移提供了一种方法来 命令式地 定义该结构(以及数据)应该如何随时间逐步改变。这种方法的优点是,它使得在保留数据的同时重命名列、合并多个列甚至随着时间的推移更改数据格式变得更加容易,同时避免了留下不再需要的旧代码,有助于保持事物的整洁。
安装
Composer
- 运行
composer require "patricknelson/silverstripe-migrations:dev-master"
- 从命令行运行
sake dev/build
以确保它已正确加载到 SilverStripe 中。
手动安装
- 下载最新的 存储库压缩文件。
- 解压文件夹
silverstripe-migrations-master
并将其重命名为migrations
。 - 将此文件夹复制到您网站的根目录。
- 从命令行运行
sake dev/build
以确保它已正确加载到 SilverStripe 中。
如何使用
此模块设置了一个名为 MigrateTask
的任务,该任务仅通过以下方式从命令行访问:
sake dev/tasks/MigrateTask [选项]
php framework/cli-script.php dev/tasks/MigrateTask [选项]
使用此任务,您可以执行以下操作:
- 运行迁移(即“up”)。
sake dev/tasks/MigrateTask up
- 撤销之前的迁移(即“down”)。
sake dev/tasks/MigrateTask down
- 为您创建一个带有模板代码的新迁移文件。
sake dev/tasks/MigrateTask make:migration_name
- 注意: 此文件将自动放置在您的项目目录中,路径为
<project>/code/migrations
。您可以通过定义一个MIGRATIONS_PATH
常量来自定义此位置,该常量应该是目标目录的绝对路径(可在您的_ss_environment.php
或_config.php
文件中定义)。此外,自动生成的迁移文件将使用Migration_
前缀进行伪命名空间,以帮助减少可能的类名冲突。
工作原理
Up
每次您运行一个 up
迁移时,此任务将遍历您在 <project>/code/migrations
文件夹(您可以自定义)中设置的迁移文件,然后将其与已运行的迁移列表进行比较(在 DatabaseMigrations
表中)。如果找到一个尚未运行的迁移,它将在该迁移文件上执行 ->up()
方法,并在该表中记录它。此外,它将确保仅根据文件名按字母数字顺序运行迁移。
Down
当同时运行多个迁移时,它们被视为一个批次,并且可以使用 down
选项一起回滚(或撤销)。当执行 down
迁移时,它们会按顺序逐批次执行,以确保一致性。
编写迁移
您可以通过运行带有 make:migration_name
选项的任务轻松生成迁移文件(将 migration_name
替换为对迁移的简洁描述,只使用下划线、字母和数字)。
示例
sake dev/tasks/MigrateTask make:change_serialize_to_json
这将生成一个符合 YYYY_MM_DD_HHMMSS_change_serialize_to_json.php
格式的文件,使用当前日期命名文件(以确保按顺序执行)并包含 Migration_ChangeSerializeToJson
类。它应该看起来像这样
<?php class Migration_ChangeSerializeToJson extends Migration { /** * Run the migrations. * * @return void */ public function up() { // Go through each DataObject and convert the column format from serialized to JSON. foreach(MyDataObject::get() as $instance) { $instance->EncodedField = json_encode(unserialize($instance->EncodedField)); } } /** * Reverse the migration (this does the opposite of the method above). * * @return void */ public function down() { // Go through each DataObject and convert the column format back from JSON to serialized again. foreach(MyDataObject::get() as $instance) { $instance->EncodedField = serialize(json_decode($instance->EncodedField)); } } }
在 Migration
类上也有一些辅助方法,可以执行常见的数据库交互,例如从表中删除列或检索不再通过 ORM 可用但仍然存在于数据库表中的列的值。
辅助方法
辅助方法的文档可以在这里找到。
运行您的迁移
在您迁移 up
或 down
之前,确保您首先运行 SilverStripe 的 dev/build
任务非常重要。例如,您可以执行以下操作
sake dev/build sake dev/tasks/MigrateTask up
这将确保迁移类都可用(在类映射中),并且您在 DataObject
中声明的字段可以供您的迁移使用。
已知问题
由于现有的 dev/build
流程独立于这些迁移运行(而不是基于迁移),您可能会运行不再适用于当前 DataObject ::$db
静态定义的给定声明状态的迁移。为了避免在更复杂的网站上出现问题,您可以在迁移中进行检查或设置新的迁移,与打包到发布分支中的代码共存,并单独部署它们(例如 release-1.2.0
或 hotfix-1.2.1
)。主要目标是确保在现有环境中可以保留和选择性地更改数据/内容,而不会丢失列、表或每次更改模式时替换整个表或数据库。
待办事项
- 添加“修剪”数据库字段和表的功能,这不仅删除了不再使用的废弃字段/表,而且还重新排序它们。这将是一个极具破坏性的功能,但如果经常(且负责任地)使用,可能会非常有帮助。
- 提供一种方法,以获取当前由
DataObject
子类定义的模式的哈希作为签名。这将有助于创建仅当当前模式/状态与特定哈希匹配时才运行的迁移。 - 设置一个
--pretend
选项,允许预览迁移(向上和向下)将执行的所有查询。