Symfony项目中带数据表字段从string转text的Doctrine迁移实现问询
问题核心结论
你当前的场景不需要额外编写读写数据的逻辑,自动生成的迁移代码本身可以直接安全执行:
- MySQL中
VARCHAR转LONGTEXT属于向上兼容的无损类型转换,原有长度不超过255的字符串可以直接适配LONGTEXT类型,不会丢失原有业务数据 - 你遇到的「Doctrine不允许执行」提示大概率是迁移工具的默认安全风险提醒,确认操作即可正常执行,执行前可以先跑
php bin/console doctrine:migrations:migrate --dry-run检查实际要执行的SQL是否符合预期
如果你确实需要在迁移中手动处理数据(比如反向从TEXT转VARCHAR需要截断、或者字段类型不兼容需要做内容转换的场景)
可以按照「新增临时字段→迁移数据→替换原字段」的逻辑修改迁移文件,参考修改后的代码如下:
final class Version20210901140835 extends AbstractMigration { public function getDescription() : string { return '将logs表old_value、new_value字段从VARCHAR改为LONGTEXT'; } public function up(Schema $schema) : void { $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.'); // 1. 新增临时LONGTEXT字段 $this->addSql('ALTER TABLE logs ADD old_value_temp LONGTEXT DEFAULT NULL, ADD new_value_temp LONGTEXT DEFAULT NULL'); // 2. 把原有字段数据同步到临时字段 $this->addSql('UPDATE logs SET old_value_temp = old_value, new_value_temp = new_value'); // 3. 删除原有VARCHAR字段 $this->addSql('ALTER TABLE logs DROP old_value, DROP new_value'); // 4. 临时字段重命名为原字段名 $this->addSql('ALTER TABLE logs CHANGE old_value_temp old_value LONGTEXT DEFAULT NULL, CHANGE new_value_temp new_value LONGTEXT DEFAULT NULL'); } public function down(Schema $schema) : void { $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.'); // 回滚逻辑和升级逻辑对称即可 $this->addSql('ALTER TABLE logs ADD old_value_temp VARCHAR(255) DEFAULT NULL COLLATE utf8mb4_unicode_ci, ADD new_value_temp VARCHAR(255) DEFAULT NULL COLLATE utf8mb4_unicode_ci'); // 如果回滚时内容超过255需要做截断可以在这里加处理逻辑,比如UPDATE logs SET old_value_temp = LEFT(old_value,255) $this->addSql('UPDATE logs SET old_value_temp = old_value, new_value_temp = new_value'); $this->addSql('ALTER TABLE logs DROP old_value, DROP new_value'); $this->addSql('ALTER TABLE logs CHANGE old_value_temp old_value VARCHAR(255) DEFAULT NULL COLLATE utf8mb4_unicode_ci, CHANGE new_value_temp new_value VARCHAR(255) DEFAULT NULL COLLATE utf8mb4_unicode_ci'); } }
注意事项
- 生产环境执行迁移前务必先备份业务数据,避免操作失误导致数据损失
- 单表数据量超过100万的场景建议在业务低峰期执行迁移,避免锁表影响线上业务
内容的提问来源于stack exchange,提问作者cervico
相关产品推荐
相关产品推荐

