Laravel 6中使用change()将列转为timestamp时迁移失败如何解决
报错原因
该报错由Laravel修改列功能依赖的Doctrine DBAL组件触发:Doctrine默认未注册MySQL的timestamp类型映射,仅在调用change()方法修改列属性时会触发类型校验,新增timestamp列的场景不走Doctrine逻辑,因此不会报错。
解决方案
方案1:注册Doctrine类型映射(兼容Laravel迁移写法)
- 在迁移文件头部引入依赖类:
use Doctrine\DBAL\Types\Type; use Doctrine\DBAL\Types\TimestampType;
- 修改up方法,先注册类型映射再执行列修改:
public function up() { // 注册timestamp类型到Doctrine if (!Type::hasType('timestamp')) { Type::addType('timestamp', TimestampType::class); } // 注册数据库字段类型到Doctrine类型的映射关系 $platform = Schema::getConnection()->getDoctrineSchemaManager()->getDatabasePlatform(); $platform->registerDoctrineTypeMapping('timestamp', 'timestamp'); Schema::table('testassignment', function (Blueprint $table) { $table->timestamp('duration')->nullable()->change(); }); }
方案2:使用原生SQL执行(绕过Doctrine校验,兼容性更强)
如果方案1仍报错,可直接用对应数据库的原生SQL执行修改,不需要依赖Doctrine:
public function up() { // 以下为MySQL语法,其他数据库请调整为对应语法 DB::statement('ALTER TABLE `testassignment` MODIFY COLUMN `duration` TIMESTAMP NULL'); }
注意事项
- 执行迁移前请提前备份表数据,避免类型转换过程中出现数据丢失
- 若列之前有非null约束、默认值等配置,可自行调整SQL语句或迁移方法的对应参数
内容的提问来源于stack exchange,提问作者Dr.Noob
相关产品推荐
相关产品推荐

