Yii 1.x中如何通过数据迁移正确修改表字段数据类型
Yii 1.x 迁移修改字段类型正确方案
不生效的核心原因
字段类型修改未生效来自两个常见操作错误:
addColumn()是Yii迁移提供的新增字段方法,仅对表中不存在的字段生效,对已存在的字段调用该方法不会触发任何表结构变更。- 直接修改已经执行过的历史迁移文件不会触发变更:Yii会在数据库的迁移版本记录表中标记所有已执行的迁移,Pipeline部署时只会运行未执行过的新迁移,修改历史文件不会触发重复执行。
正确操作流程
- 保留之前新增
running_hours字段的旧迁移文件不变,新建一个独立的迁移文件专门处理这次字段类型调整。 - 在新迁移的
up()方法中调用alterColumn()方法——这是Yii迁移专门用于修改已有字段结构的API,需要传入三个参数:目标表名、待修改字段名、新的字段完整定义。 - 补充
down()方法实现回滚逻辑,方便版本回退时恢复原有字段结构。
代码示例
<?php class m240xxx_xxxxxx_change_asset_running_hours_type extends CDbMigration { public function up() { // 修改字段为VARCHAR(8)类型,若字段有非空、默认值、注释等属性,需在类型定义后补全 // 示例完整定义:'VARCHAR(8) NOT NULL DEFAULT "" COMMENT "设备运行时长"' $this->alterColumn('asset', 'running_hours', 'VARCHAR(8)'); } public function down() { // 回滚时恢复原DECIMAL类型,注意回滚前需确认字段内现存值符合DECIMAL(4,2)范围,否则执行会失败 $this->alterColumn('asset', 'running_hours', 'DECIMAL(4,2)'); } }
补充注意事项
- 执行迁移前务必备份对应表的结构和数据,避免类型转换导致存量数据丢失或异常。如果表中数据量较大,ALTER操作可能引发锁表,建议在业务低峰期执行。
- 如果字段原有非空、默认值、索引等属性,写新字段定义时要把这些属性完整带上,否则执行修改后原有属性会丢失。
- 字段类型修改完成后,同步调整对应Yii模型内的字段验证规则,移除原针对DECIMAL类型的数值范围限制,避免和新的字符串类型逻辑冲突。
若框架自动生成的ALTER语句不符合预期,也可以直接调用
$this->execute()方法写原生SQL执行字段修改,效果和框架原生方法一致。
内容的提问来源于stack exchange,提问作者Mark Rubbinson
相关产品推荐
相关产品推荐

