Laravel 用 Chunk 存储数据

问题描述 投票:0回答:1

我需要有关 Chunk 的帮助, 下面是我向 API 端点发送请求的代码, 背景:API 端点只能接受 500 个信号,因此我从 DB 将数据分块为仅 400 个,然后将结果转换为逗号分隔的字符串。 然后将该字符串与 URL 一起发送到 API 端点,

我收到了所有 400 个结果的响应,但是在使用该数据集存储在数据库中时,它仅存储第一个结果,然后抛出错误

Undefined property: stdClass::$data

问题是如何用块存储所有 400 条记录?我的 foreach 循环在块函数内运行,

$commaSeparatedString = '';

ExchangeSymbol::where('segment', 'NSE_FO')
                        ->where('instrument_type', 'FUT')
                        ->chunk(400, function ($records) use (&$commaSeparatedString) {
                                $columnValues = $records->pluck('instrument_key')->toArray();
                                $commaSeparatedString .= implode(',', $columnValues) . '';

$url = 'https://api.upstox.com/v2/market-quote/quotes?instrument_key='.$commaSeparatedString;

$response = Http::withToken('eyJ0I')->get($url);
                    
$data = $response->object()->data;

$quote = new EodMarketQuote;

foreach($data as $d){
            $quote->open = $d->ohlc->open;
            $quote->high = $d->ohlc->high;
            $quote->low = $d->ohlc->low;
            $quote->close = $d->ohlc->close;
            $quote->save();
         }                                
   });
laravel eloquent
1个回答
0
投票

您遇到的问题似乎与您在 foreach 循环中处理数据库存储操作的方式有关,特别是考虑到您在每条记录的循环范围之外使用 $quote 对象。当您重复为相同的 $quote 对象属性分配值并调用 $quote->save() 时,您实际上是在一遍又一遍地更新相同的记录,而不是为数据集中的每个项目创建新记录。此外,错误 Undefined property: stdClass::$data 表示在某些情况下,响应对象中可能不存在预期的 data 属性,但您提到 dd($data) 显示正确的响应,因此我们将专注于存储逻辑。

为了解决存储块中所有 400 条记录的问题,您应该在循环中为每条记录实例化一个新的 EodMarketQuote 对象。这样,将为每条数据创建一个新的数据库行。以下是调整代码的方法:

ExchangeSymbol::where('segment', 'NSE_FO')
->where('instrument_type', 'FUT')
->chunk(400, function ($records) {
    $columnValues = $records->pluck('instrument_key')->toArray();
    $commaSeparatedString = implode(',', $columnValues);

    $url = 'https://api.upstox.com/v2/market-quote/quotes?instrument_key='.$commaSeparatedString;

    $response = Http::withToken('eyJ0I')->get($url);

    $data = $response->object()->data ?? []; // Add null coalescing operator to handle missing data property

    foreach ($data as $d) {
        $quote = new EodMarketQuote; // Instantiate a new object for each record

        if(isset($d->ohlc)) { // Check if ohlc property exists
            $quote->open = $d->ohlc->open;
            $quote->high = $d->ohlc->high;
            $quote->low = $d->ohlc->low;
            $quote->close = $d->ohlc->close;
            $quote->save();
        }
    }
});

主要变更和建议:

  1. 实例化
    EodMarketQuote
    循环内部:
    这可确保为数据集中的每个项目创建一个新的数据库条目。
  2. 空合并运算符 (
    ?? []
    ):
    在尝试访问
    $data
    时添加此运算符以处理响应中可能不存在
    data
    属性的情况。这可以防止脚本因“未定义的属性”错误而失败。
  3. 检查
    ohlc
    的存在性:
    在尝试访问
    ohlc
    属性之前,请检查它是否存在,以避免出现类似于您在
    $data
    中遇到的错误。

这些调整应有助于将 400 条记录中的每一条正确存储到数据库中,而不会覆盖相同的记录或因未定义的属性而遇到错误。

© www.soinside.com 2019 - 2024. All rights reserved.