You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 17:20:58