【发布时间】:2022-01-06 11:06:51
【问题描述】:
我有一个包含 500 万行的 CSV 文件。我正在使用来自 thephpleague.com 的 CSV 库。它使用生成器,因此逐行读取文件。所以阅读不会有任何问题。
然而,我想使用 CI 模型将它们保存到数据库中,因为我需要确保数据完整性可以。所以我想使用模型的验证器,beforeInsert 回调等。所以问题不是如何将数据插入数据库,而是如何通过使用模型处理插入数据。
这是我的代码:
namespace App\Util;
use App\Models\TestModel;
use League\Csv\Reader;
class CSV
{
public function readData(string $filePath, array $headers = [])
{
$filePath = ROOTPATH.'test.5mn.csv';
$maxExecutionTime = ini_get("max_execution_time");
ini_set('max_execution_time', 300);
$reader = Reader::createFromPath($filePath, 'r');
$reader->setHeaderOffset(0); //set the CSV header offset
$reader->skipEmptyRecords();
if (true === empty($headers)) {
$headers = $reader->getHeader();
}
$records = $reader->getRecords($headers);
$isGoodToGo = true;
foreach ($records as $record) {
if ($this->isEmptyWithNullValues($record)) {
continue;
}
if ($this->isEmptyWithBlankString($record)) {
continue;
}
$model = model(TestModel::class);
$model->save([
'item_type' => $record["Item Type"],
'sales_channel' => $record["Sales Channel"],
'total_profit' => $record["Total Profit"],
]);
log_message('error', '#'.$model->getInsertID() . ' saved');
$model = null;
}
ini_set('max_execution_time', $maxExecutionTime);
return $isGoodToGo;
}
....
}
在控制器上我这样称呼:
public function index()
{
$test = new CSV();
$test->readData('path', []);
dump('EXIT');
}
但我在一定数量的记录后给出了 php 内存错误。在开发环境中,在抛出内存错误后,它只能保存 123456 条记录。在生产中,它保存了 253321 条记录,然后抛出内存错误。
我认为某处存在开销,但我不是专家。在模型、连接或任何地方,有没有一种方法可以让我flush 内存.. 我在想 CI 即使在生产环境中也能保留一些数据。任何想法都会非常有帮助。谢谢。。
供参考;错误信息:
CRITICAL - 2022-01-06 11:48:09 --> 允许的内存大小为 134217728 字节已用尽(尝试分配 67108872 字节)
#0【内部函数】:CodeIgniter\Debug\Exceptions->shutdownHandler()
#1 {主要}
【问题讨论】:
-
尝试在循环外创建
$model,当然也从循环中删除$model = null; -
@RiggsFolly 在外部创建
$model并删除$model = null没有区别。
标签: php csv model-view-controller bigdata codeigniter-4