Laravel中基于MySQL视图的Eloquent模型查询报错如何解决?
错误根因
1055报错的核心原因是Laravel默认开启MySQL严格模式,启用了ONLY_FULL_GROUP_BY校验规则,而histstat视图为聚合查询生成,select *的查询方式不符合该规则要求。此外Eloquent默认假设对应表存在自增主键id、自动维护created_at/updated_at字段的逻辑,也会与无主键、无内置时间戳字段的视图产生冲突。
解决方案
- 第一步:调整视图对应模型的基础配置,关闭默认的主键、时间戳自动处理逻辑
class HistStat extends Model { use HasFactory; protected $table = 'histstat'; // 显式指定视图的唯一标识字段作为主键,若无唯一主键可任选非空字段 protected $primaryKey = 'day'; // 关闭主键自增假设 public $incrementing = false; // 若主键为非int类型,需指定主键类型 protected $keyType = 'string'; // 关闭自动时间戳维护 public $timestamps = false; protected $fillable = ['day', 'total', 'paid']; } - 第二步:调整查询逻辑或SQL校验规则,二选一即可
方案1:查询时显式指定所有查询字段,避免select *触发ONLY_FULL_GROUP_BY校验,同时推荐直接在SQL层面做偏移,提升查询性能
方案2:修改数据库连接配置,关闭严格模式或移除// 原逻辑等效写法 $dynamic = HistStat::select(['day', 'total', 'paid'])->get()->slice(14); // 性能更优的写法,直接在SQL层做偏移,无需查询全量数据 $dynamic = HistStat::select(['day', 'total', 'paid'])->offset(14)->get();ONLY_FULL_GROUP_BY规则,修改config/database.php中的mysql配置项:'mysql' => [ // 其余原有配置保持不变 'strict' => false, // 若不想全局关闭严格模式,可自定义sql_mode移除ONLY_FULL_GROUP_BY即可 // 'modes' => [ // 'STRICT_TRANS_TABLES', // 'NO_ZERO_IN_DATE', // 'NO_ZERO_DATE', // 'ERROR_FOR_DIVISION_BY_ZERO', // 'NO_ENGINE_SUBSTITUTION', // ], ] - 额外注意:MySQL视图本身为只读结构,不要对基于视图的模型执行
save()、update()、delete()等写入操作,否则会抛出错误。如果需要避免误操作,可在模型中重写相关写入方法抛出异常,或引入只读逻辑限制写入。
内容的提问来源于stack exchange,提问作者Valery Bulash
相关产品推荐
相关产品推荐

