symfony 4.2 升级到 4.4 需重点适配 doctrine migrations v2(命名空间、方法签名)、id 主键策略(postgresql 推荐 strategy="identity")、实体映射配置、生产迁移加 --no-interaction --allow-no-migration 参数,以及 doctrine_migration_versions 表的引擎与字符集。

Symfony 4.2 升级到 4.4 后,数据库迁移本身不强制要求改动,但 Doctrine 和迁移组件的行为、默认配置及兼容性细节已有调整,稍不注意就可能引发表结构误删、ID 自增丢失或部署卡住等问题。重点不在“能不能跑”,而在“会不会静默出错”。
确认 Doctrine Migrations 组件版本是否匹配
Symfony 4.4 默认使用 doctrine/doctrine-migrations-bundle v2.x(如 2.2+),而 4.2 多用 v1.x。v2 要求迁移类继承 Doctrine\Migrations\AbstractMigration(非 Doctrine\DBAL\Migrations\AbstractMigration),且 up()/down() 方法签名改为只接收 Schema 对象(不再传 Doctrine\DBAL\Schema\Schema 或 $connection)。
若旧迁移文件仍用 v1 风格:
- 方法参数含
$connection或$schema类型提示为老命名空间 → 执行时会报ArgumentCountError或类型不匹配 - 解决办法:批量重命名命名空间,或运行
composer require doctrine/doctrine-migrations-bundle:^2.0 --update-with-dependencies后用php bin/console doctrine:migrations:sync-metadata-storage修复元数据表结构
检查 ID 主键策略是否在 PostgreSQL/MySQL 中持续生效
4.4 中 Doctrine ORM v2.7+ 对 @ORM\GeneratedValue 的解析更严格。若你沿用类似写法:
/** * @ORM\Id * @ORM\GeneratedValue(strategy="AUTO") * @ORM\Column(type="integer") */ private $id;
在 MySQL 下仍可用,但在 PostgreSQL 中可能被降级为普通整数列——尤其当之前迁移用的是 SEQUENCE 但未声明 sequenceName。升级后 doctrine:migrations:diff 更容易“纠正”这个“不一致”,结果反把自增逻辑删掉。
建议统一改用语义明确的策略:
- MySQL:保留
strategy="AUTO"或显式strategy="IDENTITY"(需 MySQL 8.0+) - PostgreSQL:必须用
strategy="IDENTITY"(推荐)或完整声明@ORM\SequenceGenerator(sequenceName="xxx_seq")
生成迁移前先清空 dev 环境缓存并验证实体映射
4.4 加强了自动映射扫描逻辑,但若 config/packages/doctrine.yaml 中 doctrine.orm.auto_mapping 为 false,或 mappings 段漏配 App\Entity\*,make:migration 或 doctrine:migrations:diff 会提示 “No changes detected”,即使实体已改。
执行前务必:
- 运行
php bin/console cache:clear --env=dev - 再执行
php bin/console debug:config doctrine | grep -A 10 mappings,确认entity_managers.default.mappings包含你的实体路径 - 最后跑一次
php bin/console doctrine:schema:update --dump-sql,看输出是否符合预期
生产环境迁移命令必须加 --no-interaction --allow-no-migration
Symfony 4.4 的 doctrine:migrations:migrate 在无新迁移时默认返回退出码 1(失败),CI/CD 流水线会直接中断。这不是 bug,是 v2 行为变更。
上线脚本中必须写成:
php bin/console doctrine:migrations:migrate --no-interaction --allow-no-migration --env=prod
否则一次空迁移就会导致部署失败。
别忽略 doctrine_migration_versions 表的存储引擎和字符集
4.4 默认要求该表使用 InnoDB(非 MyISAM),且字符集应为 utf8mb4。若旧库用的是 utf8 或 MyISAM,升级后首次 migrate 可能报 Specified key was too long 或锁表失败。
可手动修正:
ALTER TABLE doctrine_migration_versions CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; ALTER TABLE doctrine_migration_versions ENGINE=InnoDB;
之后再执行迁移。
不复杂但容易忽略











