Laravel 自定义 Artisan 命令在完成 50% 时停止
Laravel custom Artisan command stops at 50 percent completion
所以我有一个自定义的 artisan 命令,我编写它来插入一个列并将其存储到一个新列中。我有一个进度条,出于某种原因,当命令完成 50% 时,它会跳到 100%。问题是它只对一半数据执行了代码。
我正在使用 chunk() 函数将数据分成 1,000 行的块,以消除内存耗尽问题。这是必要的,因为我的数据集非常大。
我查看了我的 PHP 错误日志、MySQL 错误日志和 Laravel 日志。我找不到与此命令有关的任何错误或日志行。甚至开始寻找问题的新地方的任何想法。
$jobTitles = ModelName::where($columnName, '<>', '')
->whereNull($slugColumnName)
->orderBy($columnName)
->chunk(1000, function($jobTitles) use($jobCount, $bar, $columnName, $slugColumnName)
{
foreach($jobTitles as $jobTitle)
{
$jobTitle->$slugColumnName = Str::slug($jobTitle->$columnName);
$jobTitle->save();
}
$bar->advance(1000);
});
$bar->finish();
发生的事情是 whereNull($slugColumnName)
与回调 设置 的结合,$slugColumnName
导致后续循环丢失结果。
事件的顺序是这样的:
- 获取第一组行:
select * from table where column is null limit 100;
- 对于每一行,将列设置为一个值。
- 获取下一组行:
select * from table where column is null limit 100 offset 100;
。
- 继续并增加偏移量,直到不再有结果。
这里的问题是,在第二步之后,您从总数中删除了 100 个结果。假设您从 1000 行开始,到第二个查询时,您现在只有 900 行匹配。
当前 100 行尚未被触及时,这会导致偏移看似 跳过 整个块,从第 100 行开始。
更多官方文档请见this section of this section on chunking。
我尚未对此进行测试以验证它是否按您的用例预期工作,但使用 chunkById
似乎可以解决此问题并更正您的结果。
所以我有一个自定义的 artisan 命令,我编写它来插入一个列并将其存储到一个新列中。我有一个进度条,出于某种原因,当命令完成 50% 时,它会跳到 100%。问题是它只对一半数据执行了代码。
我正在使用 chunk() 函数将数据分成 1,000 行的块,以消除内存耗尽问题。这是必要的,因为我的数据集非常大。
我查看了我的 PHP 错误日志、MySQL 错误日志和 Laravel 日志。我找不到与此命令有关的任何错误或日志行。甚至开始寻找问题的新地方的任何想法。
$jobTitles = ModelName::where($columnName, '<>', '')
->whereNull($slugColumnName)
->orderBy($columnName)
->chunk(1000, function($jobTitles) use($jobCount, $bar, $columnName, $slugColumnName)
{
foreach($jobTitles as $jobTitle)
{
$jobTitle->$slugColumnName = Str::slug($jobTitle->$columnName);
$jobTitle->save();
}
$bar->advance(1000);
});
$bar->finish();
发生的事情是 whereNull($slugColumnName)
与回调 设置 的结合,$slugColumnName
导致后续循环丢失结果。
事件的顺序是这样的:
- 获取第一组行:
select * from table where column is null limit 100;
- 对于每一行,将列设置为一个值。
- 获取下一组行:
select * from table where column is null limit 100 offset 100;
。 - 继续并增加偏移量,直到不再有结果。
这里的问题是,在第二步之后,您从总数中删除了 100 个结果。假设您从 1000 行开始,到第二个查询时,您现在只有 900 行匹配。
当前 100 行尚未被触及时,这会导致偏移看似 跳过 整个块,从第 100 行开始。
更多官方文档请见this section of this section on chunking。
我尚未对此进行测试以验证它是否按您的用例预期工作,但使用 chunkById
似乎可以解决此问题并更正您的结果。