symfony 2 通过 doctrine migrations 实现数据库结构版本控制,非查询语句管理;生成迁移需先完善实体注解(@orm\entity、@orm\column),再运行 php app/console doctrine:migrations:diff;执行前须验证状态、检查 sql 兼容性并确保 transactional: true。

Symfony 2 本身不内置数据库迁移功能,所谓“查询版本控制”实际指通过 Doctrine Migrations(配合 DoctrineMigrationsBundle)对数据库 结构变更 进行版本化管理——不是管理 SQL 查询语句,而是管理表、字段、索引等 schema 的增删改。回滚也仅针对这些结构操作,且依赖你手动编写的逻辑。
迁移文件怎么生成?别手写 SQL
Doctrine 不靠人工写 SQL,而是对比你的实体类(Entity)和当前数据库状态,自动生成安全、可逆的 PHP 迁移类:
- 确保实体类有完整注解:@ORM\Entity + @ORM\Table 缺一不可;新增字段必须带 @ORM\Column(哪怕只是
@ORM\Column(type="string")) - 运行命令:
php app/console doctrine:migrations:diff(Symfony 2 使用app/console,非bin/console) - 如果没生成内容,大概率是实体未被识别(注解缺失)、字段已在库中存在但实体未同步,或连接配置指向了错误数据库
回滚不是自动反向,down() 必须手写
执行 doctrine:migrations:rollback 时,系统只调用迁移文件里的 down() 方法——它不会根据 up() 自动推导反向操作:
- 例如
up()中添加了 email 字段,down()就得明确写$schema->getTable('user')->dropColumn('email'); - 删除整张表、修改列类型(如 string → text)、清空数据等操作默认不可安全回滚,应避免在生产迁移中使用
- 回滚失败常见原因:字段已被其他迁移引用、
down()没处理外键或约束、事务被禁用(检查doctrine_migrations.yml中transactional: true)
迁移状态与执行前必查三件事
上线前跳过验证极易引发生产事故:
- 运行
php app/console doctrine:migrations:status,确认新版本号出现在 “Available migrations” 里,且未出现在 “Executed migrations” 中 - 打开生成的迁移文件,检查是否含
$this->addSql()—— 如果有,确认语句兼容目标数据库(比如 MySQL 的AUTO_INCREMENT在 PostgreSQL 不可用) - 确认迁移在事务中执行:
config/packages/doctrine_migrations.yml(或 Symfony 2 的app/config/config.yml)中transactional: true已启用(默认开启,老项目可能被关)
只管特定前缀的表?用 schema_filter
若数据库中混有第三方表(如 WordPress 的 wp_ 表),不想被迁移影响,可在 Doctrine 配置中加过滤规则:
- 在
app/config/config.yml的doctrine.dbal下添加:
这个正则表示只处理以 pp_ 开头的表名。注意波浪线 ~ 是分隔符,不是引号;改完需清缓存:php app/console cache:clear,否则 diff 仍按旧规则扫描。











