如何配置Doctrine生成保守迁移并标记破坏性迁移?
Doctrine 保守迁移配置与破坏性变更处理
一、配置默认生成保守迁移
保守迁移要求仅添加新表/字段,不执行删除、重命名操作,确保多版本代码兼容同一数据库。以下是实现方式:
1. 自定义迁移生成器(推荐)
通过自定义生成器过滤掉破坏性SQL语句:
- 创建自定义生成器类,继承Doctrine默认的
MigrationGenerator:
<?php namespace App\Migration; use Doctrine\Migrations\Generator\MigrationGenerator; use Doctrine\DBAL\Schema\SchemaDiff; class ConservativeMigrationGenerator extends MigrationGenerator { protected function generateUpSql(SchemaDiff $schemaDiff): array { $sqls = parent::generateUpSql($schemaDiff); // 过滤DROP、RENAME相关SQL return array_filter($sqls, function($sql) { return !str_starts_with(strtoupper($sql), 'DROP ') && !str_starts_with(strtoupper($sql), 'RENAME '); }); } }
- 在Symfony配置文件
config/packages/doctrine_migrations.yaml中指定自定义生成器:
doctrine_migrations: generator: class: App\Migration\ConservativeMigrationGenerator
2. 命令行生成时过滤
每次生成迁移时,通过自定义过滤器跳过破坏性操作:
php bin/console doctrine:migrations:diff --filter=App\Migration\ConservativeFilter
过滤器类示例:
<?php namespace App\Migration; use Doctrine\Migrations\Filter\FilterInterface; use Doctrine\DBAL\Schema\SchemaDiff; class ConservativeFilter implements FilterInterface { public function accept(SchemaDiff $schemaDiff): bool { // 移除删除、重命名的变更 $schemaDiff->removedTables = []; $schemaDiff->changedTables = array_filter($schemaDiff->changedTables, function($tableDiff) { $tableDiff->removedColumns = []; $tableDiff->renamedColumns = []; $tableDiff->renamedIndexes = []; return !empty($tableDiff->addedColumns) || !empty($tableDiff->addedIndexes); }); return true; } }
3. 实体映射规范
团队约定:修改实体时仅添加新字段/关联,不删除或重命名原有映射。旧字段标记为@deprecated,待所有代码版本不再使用后再处理。
二、创建并标记破坏性变更迁移
破坏性变更(删除/重命名表、字段)需手动创建并明确标记,避免误执行:
1. 手动生成迁移文件
使用命名约定明确标识破坏性操作:
php bin/console doctrine:migrations:generate --name=DropObsoleteUserOldPhoneColumn
2. 明确标记与注释
在迁移类中通过注释和描述字段标记为破坏性变更:
<?php declare(strict_types=1); namespace DoctrineMigrations; use Doctrine\DBAL\Schema\Schema; use Doctrine\Migrations\AbstractMigration; /** * 破坏性变更:删除users表中废弃的old_phone字段 * 前置条件:所有线上代码已移除对该字段的依赖 */ final class Version20240520123456DropObsoleteUserOldPhoneColumn extends AbstractMigration { public function getDescription(): string { return 'Drop obsolete old_phone column from users table [破坏性变更]'; } public function up(Schema $schema): void { $this->addSql('ALTER TABLE users DROP COLUMN old_phone'); } public function down(Schema $schema): void { // 可选:添加回滚逻辑,便于紧急恢复 $this->addSql('ALTER TABLE users ADD old_phone VARCHAR(255) DEFAULT NULL'); } }
3. 团队执行规范
- 所有破坏性迁移必须在
getDescription()中包含[破坏性变更]标记,代码评审时重点校验。 - 执行前需确认:所有部署环境的代码已不再使用目标字段/表,可通过代码扫描、日志分析验证。
- 执行时建议先在预发布环境测试,再分批部署到生产环境。
内容的提问来源于stack exchange,提问作者Web-Fu
相关产品推荐
相关产品推荐

