symfony 4.3 升级至 4.4 后迁移 sql 差异源于 doctrine 组件升级:1. postgresql id 策略改用 generated by default as identity;2. 字段类型推导增加长度校验;3. 索引名校验更严格;4. 多 em 场景下 --em 参数行为更明确。

Symfony 4.3 和 4.4 本身不直接生成 SQL,真正负责生成迁移 SQL 的是 Doctrine DBAL 和 Doctrine Migrations,而它们的版本升级(尤其是 Doctrine ORM 2.7 → 2.8、DBAL 2.10 → 2.12)在 Symfony 4.3 升级到 4.4 过程中常伴随更新。因此,SQL 差异并非来自 Symfony 框架层,而是来自底层 Doctrine 组件对元数据解析、平台适配和默认行为的调整。以下是实际影响迁移 SQL 生成的关键差异点:
1. PostgreSQL 中 ID 策略的默认行为变化
Symfony 4.4 常搭配 Doctrine ORM 2.8+ 和 DBAL 2.12+,后者对 PostgreSQL 的 IDENTITY 列支持更完善:
- 在 4.3(Doctrine @ORM\GeneratedValue(strategy="SEQUENCE") 但未声明
sequenceName,diff 可能生成危险 SQL(如移除DEFAULT nextval(...)),导致 auto-increment 失效; - 到 4.4(Doctrine ≥2.8),
strategy="IDENTITY"被正式推荐并安全支持,doctrine:migrations:diff会生成GENERATED BY DEFAULT AS IDENTITY语句,不再依赖手动序列,SQL 更简洁且幂等。
2. 字段类型推导更严格,减少隐式转换
- 4.3 时期 DBAL 对
@ORM\Column(type="string")未指定length时,可能默认推导为VARCHAR(255)并忽略数据库中已存在的VARCHAR(191);diff 往往不触发变更。 - 4.4 配合 DBAL 2.12 后,类型比对增加长度校验维度。若数据库字段是
VARCHAR(191)而实体未声明length=191,diff会生成ALTER COLUMN ... TYPE VARCHAR(255)—— 这在 MySQL 中可能失败(需显式USING转换),提示更早暴露不一致。
3. 索引与唯一约束处理更保守
- 4.3 的
diff对索引名不敏感(如UNIQ_abcvsemail_unique),只要字段组合相同就认为一致; - 4.4+ 的 Doctrine DBAL 开始校验索引定义完整性。若实体用
@ORM\UniqueConstraint(columns={"email"}),但数据库里是手建的命名索引且名称不匹配,diff可能生成DROP INDEX ...+CREATE UNIQUE INDEX ...,而非跳过。
4. 多数据库场景下 --em 参数行为更明确
- Symfony 4.3 中
doctrine:migrations:diff默认只扫描主 EntityManager,即使配置了多个连接,也容易漏检其他库的结构差异; - 4.4+(DoctrineBundle 2.2+)强化了
--em参数校验:未指定且存在多 EM 时会报错提醒,避免生成空迁移或遗漏变更。
⚠️ 注意:这些差异不会自动“修复”旧项目。如果你从 4.3 升级到 4.4 后运行
doctrine:migrations:diff突然生成大量 SQL,大概率是 Doctrine 新版本暴露了之前被忽略的元数据-数据库不一致(比如字段长度缺失、序列未声明、索引名偏差)。建议升级后先运行doctrine:schema:validate,再清理缓存(cache:clear)、重试 diff。
不复杂但容易忽略











