Symfony 数据迁移依赖 Doctrine Migrations,通过时间戳迁移文件实现数据库结构版本控制;需先修改实体并执行 diff 生成迁移,执行前须验证状态、检查 SQL 兼容性及事务配置,回滚需手动编写 down() 方法,严禁篡改迁移记录表。

Symfony 数据迁移用的是 Doctrine Migrations,它不是辅助工具,而是生产环境必须依赖的数据库结构版本控制机制。核心思路是:把每次表结构变更写成带时间戳的 PHP 类文件,通过命令驱动执行或回滚,全程可追溯、可协作、可自动化。
生成迁移文件:改实体,再 diff
不要手动编写迁移类。正确流程是:
- 先修改实体类(比如加一个 $email 属性,并配上
@ORM\Column(type="string", length=255)) - 运行命令:
php bin/console doctrine:migrations:diff - 它会自动比对实体定义和当前数据库结构,生成类似
Version20260513142000.php的文件到migrations/目录
如果没生成内容,检查实体是否漏了 @ORM\Entity 注解;若提示 “No changes detected”,可能是数据库已有字段但实体未同步,或误用了已废弃的 doctrine:generate:entities 命令。
执行迁移前必须确认三件事
迁移会真实修改数据库,跳过验证极易出错:
- 运行
php bin/console doctrine:migrations:status,确认新生成的版本出现在 “Available migrations” 列表中,且未出现在 “Executed migrations” 中 - 打开刚生成的迁移文件,检查
up()方法里有没有手写的$this->addSql()—— 如果有,需人工核对 SQL 是否兼容目标数据库(如 MySQL 和 PostgreSQL 对 UUID 字段写法不同) - 确认事务已启用:查看
config/packages/doctrine_migrations.yaml,确保transactional: true(默认开启,但老项目可能被改过)
执行与回滚:migrate 和 rollback
执行迁移:
-
php bin/console doctrine:migrations:migrate—— 执行所有待处理迁移 - 加
--no-interaction可跳过确认(适合 CI/CD)
回滚操作不能“自动反向”:
-
php bin/console doctrine:migrations:rollback会调用你迁移文件中写的down()方法 - 这个方法不会自动生成,必须手动编写逻辑(比如
$schema->dropColumn('email', 'user')),且要保证它能安全撤销up()的全部操作 - 常见失败原因:字段在
down()中被删了,但其他迁移又依赖它;或写了不支持回滚的操作(如删除整张表)
状态管理与注意事项
Doctrine 用一张叫 doctrine_migration_versions 的表记录哪些迁移已执行,严禁手动删它或删迁移文件。多数据库时,doctrine:migrations:diff 默认只作用于默认连接,需显式加 --em=other_manager 指定实体管理器。另外,up() 中用 $schema->createTable() 是安全的,但直接写 $this->addSql('DROP TABLE users') 属于高危行为,除非你完全清楚后果。











