一个模块里有三个 Data
Patch:先创建默认数据,再补关联关系,最后迁移旧配置。只把类名写成
Patch01、Patch02
并不能保证执行顺序,文件时间也不可靠。Magento 判断顺序看的是 patch
之间声明的依赖。
后执行的Patch明确返回它依赖的类
use Magento\Framework\Setup\Patch\DataPatchInterface;
class AssignDefaultGroup implements DataPatchInterface
{
public static function getDependencies(): array
{
return [
CreateDefaultGroup::class,
];
}
public function apply(): void
{
// CreateDefaultGroup 已完成后再写关联数据
}
public function getAliases(): array
{
return [];
}
}
如果 Patch C 必须在 A、B
都完成之后执行,就同时返回两个类。依赖可以跨模块,但对方模块也应该在
module.xml 的 sequence 或 Composer
依赖中体现安装关系,避免代码根本未安装。
只给真正的数据依赖排序
两个 Patch
操作互不相关的表,就不必为了“看起来整齐”串成一条长链。依赖越多,循环依赖和后续重构越麻烦。判断标准很简单:前一个
Patch 没有执行,后一个是否必然失败或产生错误数据?只有答案为是,才写进
getDependencies()。
patch_list有记录后,改apply不会重新执行
SELECT patch_name
FROM patch_list
WHERE patch_name LIKE 'Vendor\\Module\\Setup\\Patch\\Data\\%';
Data Patch 成功后会记录类名。你后来修改 apply(),Magento
不会再次执行它。开发环境可以在确认数据可回滚后删除对应记录重测;生产环境不要随便删
patch_list,应该新增一个 Patch 来做后续变更。
如果只是给类改名,需要通过 getAliases()
返回旧类名,避免升级站点把同一份变更再跑一次。
在空库和升级库各跑一遍
空库测试能验证完整依赖排序,已有数据库升级测试能验证历史 patch
记录、类重命名和新增 patch
的组合。执行后除了看命令成功,还要核对业务表和
patch_list。Patch
的目标是可重复部署同一个结果,不是依赖某台服务器恰好按文件名顺序扫描。

