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

Laravel使用hydrate填充模型仅主键有值其余字段为空如何解决

问题原因

你没有错误使用hydrate()方法,问题出在SQL查询逻辑:

  • 你使用SELECT *对两张表做左关联查询,除了关联键operation_id(使用USING关键字查询结果只会保留一个)外,两张表的同名字段会被后查询的operations表字段覆盖。
  • 由于你筛选的是o.operation_id IS NULL的记录,operations表的所有字段返回值都是null,因此最终拿到的查询结果里除了operation_id,其余字段都是空值,才会出现插入后只有主键有值的情况。

修复方案

快速修复

只需将SQL语句中的SELECT *修改为SELECT u.*,明确只取upload_operations表的字段即可解决空值问题:

$new_uploads = DB::select('
    SELECT
    u.*
    FROM
    upload_operations u
    LEFT JOIN operations o USING (operation_id)
    WHERE
    o.operation_id IS NULL');

更优实现方案

你当前的逐行插入方案性能较差,数据量大时容易超时,推荐用查询构造器+批量插入的方式实现,逻辑更简洁性能更高:

public function handle()
{
    // 直接查询出所有待新增的上传记录
    $toInsert = UploadOperation::whereNotIn('operation_id', Operation::pluck('operation_id'))
        ->get()
        ->map(fn ($record) => $record->only([
            'certifier_name',
            'certifier_website',
            'certifier_email_address',
            'operation_id',
            'operation_name',
            // 其余需要同步的字段
        ]))
        ->toArray();

    Log::info('New operations count: ' . count($toInsert));

    // 批量插入,避免循环逐行写入
    if (!empty($toInsert)) {
        Operation::insert($toInsert);
    }

    return Action::message('New uploads added!');
}

增量同步通用方案

如果需要同时处理新增和更新的同步需求,不需要自己做表关联比对,可以直接使用Laravel内置的upsert方法一步完成:

public function handle()
{
    $allUploads = UploadOperation::all()->toArray();
    Log::info('Upload operations count: ' . count($allUploads));

    // 第一个参数为待写入数据,第二个参数为冲突判断主键,第三个参数为冲突时需要更新的字段
    Operation::upsert(
        $allUploads,
        ['operation_id'],
        ['certifier_name', 'certifier_website', 'certifier_email_address', 'operation_name']
    );

    return Action::message('Uploads synced successfully!');
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 03:45:01