必须先执行 doctrine:migrations:status 确认待迁移版本存在,再人工检查迁移文件中的高危 SQL、事务配置及跨库兼容性,生产环境须手动执行并禁用自动脚本。

直接执行 php bin/console doctrine:migrations:migrate 是危险操作,必须先确认状态、检查 SQL、确保事务开启,否则可能破坏生产库结构。
怎么确认迁移文件已生成且待执行
别跳过这步——很多“迁移没生效”问题其实是根本没生成文件或生成了但没被识别。
- 运行
php bin/console doctrine:migrations:status,重点看 “Available migrations” 是否列出你期望的版本(如Version20260310190500) - 如果显示
No migrations available,检查migrations/目录是否存在 PHP 文件;若为空,说明doctrine:migrations:diff没触发,常见原因是实体类没加@ORM\Entity或数据库里字段已存在但实体未同步 - 多数据库项目要加
--em=other_manager,否则默认只扫描 default 连接
执行前必须人工核对的三件事
Doctrine 不会替你判断业务影响,up() 里的 SQL 是它生成的,但是否安全得你自己看。
- 打开刚生成的迁移文件(如
migrations/Version20260310190500.php),检查$this->addSql()语句:有没有DROP TABLE、MODIFY COLUMN这类高危操作?MySQL 和 PostgreSQL 对UUID、JSON字段的语法不同,跨库部署时尤其要盯紧 - 确认
config/packages/doctrine_migrations.yaml中transactional: true已启用(老项目可能被手动关掉);禁用事务会导致部分失败后数据库处于中间状态 - 开发环境可加
--dry-run预览将执行的 SQL:php bin/console doctrine:migrations:migrate --dry-run
生产环境迁移必须绕过交互且由专人执行
自动脚本在 prod 环境执行迁移是反模式,CI/CD 流程里也不该让它自己跑完。
- 命令必须带
--no-interaction,否则卡在 “Are you sure?” 提示上;但更关键的是——它不该出现在post-install-cmd或部署脚本末尾无条件执行 - 团队应约定:所有 prod 迁移由 DBA 在跳板机手动执行,且执行前比对
doctrine:migrations:status --show-versions输出,确认无跳过、无冲突版本 - 关键变更(如重命名字段、大表
ADD COLUMN)需附带回滚 SQL 脚本,存于docs/migrations/并经两人签字;Doctrine 的down()方法不是万能的,尤其是涉及数据迁移时
最容易被忽略的点是:迁移状态由 doctrine_migration_versions 表维护,这个表绝不能手动删、不能清空、不能用其他工具改——哪怕只是想“重置迁移历史”,也得走 doctrine:migrations:version --delete 这种受控方式。











