haoa / migration
Lightweight versioned database migrations for Haoa projects
Requires
- php: >=7.2
- ext-pdo: *
- haoa/cli: ^1.0
- haoa/mix-database: ^2.0
Requires (Dev)
- phpunit/phpunit: ^8.5 || ^9.6 || ^10.5
Suggests
None
Provides
None
Conflicts
None
Replaces
None
This package is not auto-updated.
Last update: 2026-10-15 06:18:54 UTC
README
基于 haoa/cli 和 haoa/mix-database 的轻量数据库迁移库,支持 MySQL 和 PostgreSQL。
安装
composer require haoa/migration
项目配置
绑定项目数据库实例和迁移目录:
use App\Container\DB\DB; use Haoa\Migration\Migration; Migration::setDatabaseResolver(function () { return DB::instance(); }); Migration::setMigrationPath(BASE_PATH . '/database/migrations');
手动注册命令:
use Haoa\Migration\MigrationCommandProvider; $cmds = array_merge($cmds, MigrationCommandProvider::commands()); Cli::addArrCommand(...$cmds)->run();
使用
php bin/cli.php migrate:make create_users_table php bin/cli.php migrate:run
迁移文件返回一个带公开 up() 方法的对象。默认不自动开启事务,up() 成功后登记版本;可通过 withinTransaction 为单个迁移开启事务。发生异常时停止后续迁移。
<?php declare(strict_types=1); use App\Container\DB\DB; return new class { public function up(): void { DB::instance()->raw('CREATE TABLE users (id BIGINT PRIMARY KEY)', []); } };
事务开关
自动事务默认关闭,不区分数据库类型。迁移文件可以通过公开的布尔属性 withinTransaction 控制;未声明该属性时视为 false。
需要将迁移内容与版本登记放入同一个事务时,在对应迁移对象中显式开启:
return new class { /** @var bool 开启此迁移的自动事务。 */ public $withinTransaction = true; /** 执行迁移 */ public function up(): void { // 在此编写迁移代码,事务由迁移库统一管理。 } };
自动事务开启时,执行顺序为:开始事务 → up() → 登记版本 → 提交。事务只覆盖当前文件,不会将全部待执行文件放入同一个事务。up() 中的数据库操作必须使用配置的同一个数据库实例;不要自行提交或回滚迁移库管理的事务。
开关只控制迁移库是否调用事务接口,不改变数据库本身的能力。MySQL 等数据库的部分 DDL 会隐式提交,开启开关也不能保证整个迁移原子回滚;此类迁移可关闭自动事务。其他连接、文件操作和外部请求也不在此事务的回滚范围内。
关闭自动事务时,up() 成功后仍会登记版本;如果内容已提交但登记失败,应先核对数据库状态,再处理执行记录,避免直接重跑。
已执行迁移的判断流程
运行 migrate:run 时,按以下流程判断和执行迁移:
- 扫描迁移目录中的文件,按文件名中的版本号排序。
- 获取迁移锁,确保迁移任务不会并发执行;如果
schema_migrations表不存在,则自动创建。 - 一次查询
schema_migrations中所有已执行的版本号,并保存在内存中。 - 逐个检查迁移文件的版本号:已经登记的跳过;未登记的根据
withinTransaction开关开启事务,再执行其up()方法。 - 每个迁移执行成功后,将版本号、迁移名称和执行时间写入
schema_migrations,若已开启自动事务则提交;执行或登记失败时尝试回滚已开启的自动事务。 - 任务结束时释放迁移锁;发生异常时也会尝试释放锁。
是否执行过的判断在内存中完成,不会为每个迁移文件单独查询数据库,也不是只判断最大的版本号。后来补入的较小版本号,只要尚未登记,也会被执行。
执行记录的保留
schema_migrations 每个迁移文件只保存一条记录,通常无需定期清理。迁移文件和对应的执行记录应长期保留,用于防止重复执行。
删除执行记录后,如果对应的迁移文件仍在目录中,下次运行会再次执行该文件,可能导致重复建表或重复插入数据。