Laravel Chunk批量存储数据求助:仅存首条且报属性未定义错
问题解决:通过Chunk分块实现400条记录完整存储
问题根源分析
你遇到的两个核心问题:
- 请求参数错误导致无data返回:外部定义的
$commaSeparatedString用引用传递进chunk回调,每次chunk都会把新的instrument_key追加进去,导致后续请求的参数是多批次的累加值,超过API限制后返回的响应没有data字段,触发Undefined property: stdClass::$data错误。 - 模型实例复用导致仅存第一条:循环里一直用同一个
$quote实例,第一次save()是创建新记录,之后的save()会变成更新这条已存在的记录,所以只有第一条数据被保存。
修正后的代码
ExchangeSymbol::where('segment', 'NSE_FO') ->where('instrument_type', 'FUT') ->chunk(400, function ($records) { // 每次chunk单独生成当前批次的instrument_key字符串,不再累加 $instrumentKeys = $records->pluck('instrument_key')->toArray(); $commaSeparatedString = implode(',', $instrumentKeys); $url = 'https://api.upstox.com/v2/market-quote/quotes?instrument_key=' . $commaSeparatedString; $response = Http::withToken('eyJ0I')->get($url); // 先做响应校验,避免无data时报错 if (!$response->successful() || !isset($response->object()->data)) { // 这里可以加日志记录错误,比如Log::error('API请求失败', ['response' => $response->body()]); return; } $data = $response->object()->data; // 用create方法直接创建新记录,无需复用实例 foreach ($data as $d) { EodMarketQuote::create([ 'open' => $d->ohlc->open, 'high' => $d->ohlc->high, 'low' => $d->ohlc->low, 'close' => $d->ohlc->close, ]); } });
关键修改说明
- 取消参数累加:移除外部的
$commaSeparatedString定义,每次chunk内部生成当前批次的字符串,确保每次请求的参数都是当前400条的instrument_key,不会超长。 - 增加响应校验:先判断请求是否成功,且响应中存在
data字段,避免后续代码因无data而报错。 - 改用create方法:每次循环通过
create()创建新的模型实例,自动完成创建和保存,同时避免复用实例导致的更新问题。注意需要在EodMarketQuote模型中设置可批量赋值的字段:class EodMarketQuote extends Model { protected $fillable = ['open', 'high', 'low', 'close']; // 或者设置 $guarded = []; 允许所有字段批量赋值 }
内容的提问来源于stack exchange,提问作者rjcode
相关产品推荐
相关产品推荐

