You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Media Library v9升级添加generated_conversions列迁移报错排查

报错根因
  • 列缺失触发的SQLSTATE[42S22]错误:spatie/laravel-medialibrary v9版本迭代后,将原本嵌套在custom_properties JSON字段内的generated_conversions数据拆分为独立的顶层JSON列,旧版本media表未新增该字段时,执行媒体写入的INSERT操作就会触发列不存在的报错。
  • 迁移执行触发的SQLSTATE[42000] 1064语法错误:迁移代码中使用的->JSON路径简化操作符仅对MySQL 5.7.9+原生支持,MariaDB对该语法的兼容存在版本差异;同时原查询条件中针对JSON字段的空字符串等值判断,会触发隐式类型解析冲突,最终导致SQL语法解析失败。
分步修复方案

1. 迁移文件语法兼容调整

  • 替换MariaDB不兼容的JSON取值语法
    原代码中使用的custom_properties->"$.generated_conversions"简化写法,替换为全版本兼容的标准JSON函数逻辑,同时增加空值兜底,避免给JSON字段写入非合规格式的值:
    // 原错误写法
    'generated_conversions' => DB::raw('custom_properties->"$.generated_conversions"'),
    
    // 兼容MariaDB的正确写法
    'generated_conversions' => DB::raw("IFNULL(JSON_UNQUOTE(JSON_EXTRACT(custom_properties, '$.generated_conversions')), JSON_OBJECT())"),
    
  • 调整查询过滤条件
    原代码中针对JSON字段匹配空字符串的逻辑不符合JSON类型字段的存储规则,是触发语法报错的诱因之一,替换为原生JSON校验逻辑:
    // 原容易触发语法错误的写法
    Media::query()
        ->whereNull('generated_conversions')
        ->orWhere('generated_conversions', '')
        ->orWhereRaw("JSON_TYPE(generated_conversions) = 'NULL'")
    
    // 兼容MariaDB的正确写法
    Media::query()
        ->where(function ($query) {
            $query->whereNull('generated_conversions')
                ->orWhereRaw("JSON_TYPE(generated_conversions) = 'NULL'")
                ->orWhereRaw("JSON_LENGTH(generated_conversions) = 0");
        })
    
  • 给新增列增加符合扩展包要求的默认值
    避免新插入的媒体记录因为字段为null触发扩展包的校验错误,在建列语句中补充默认空对象值:
    Schema::table('media', function (Blueprint $table) {
        $table->json('generated_conversions')->default(DB::raw('(JSON_OBJECT())'));
    });
    
  • 回滚逻辑兼容性说明
    迁移down方法中如果启用注释里的字段回写逻辑,因为本身使用的是标准JSON_SET函数,MariaDB可直接兼容,不需要额外调整语法。

2. 迁移执行注意事项

  • 不要使用php artisan migrate:fresh --seed执行升级迁移,该命令会清空全表数据,直接跳过旧数据迁移的实际意义。正确操作流程为:先备份现有media表数据,单独执行这个升级迁移文件完成旧数据转换,再运行扩展包的核心安装迁移逻辑,避免列定义重复冲突。
  • 迁移执行前可先在数据库客户端单独运行转换SQL做语法校验:
    UPDATE media 
    SET generated_conversions = IFNULL(JSON_UNQUOTE(JSON_EXTRACT(custom_properties, '$.generated_conversions')), JSON_OBJECT())
    WHERE generated_conversions IS NULL 
      OR JSON_TYPE(generated_conversions) = 'NULL'
      OR JSON_LENGTH(generated_conversions) = 0;
    
    确认SQL执行无报错后,再运行对应Artisan迁移命令。

内容的提问来源于stack exchange,提问作者AlmoDev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.25 06:45:03