gpt4 book ai didi

PHP 将大型 CSV 文件导入 MySQL 表

转载 作者:行者123 更新时间:2023-11-30 23:08:53 24 4
gpt4 key购买 nike

我需要运行一个每日 cron 作业,该作业迭代一个 6 MB 的 CSV 文件,将大约 10,000 个条目中的每一个插入到 MySQL 表中。我编写的代码在一段时间后挂起并产生超时。

if (($handle = fopen($localCSV, "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$dbdata = array(
'SiteID' => $siteID,
'TimeStamp' => $data[0],
'ProductID' => $data[1],
'CoordX' => $data[2],
'CoordY' => $data[3]
);
$row++;
$STH = $DBH->prepare("INSERT INTO temp_csv (SiteID,TimeStamp,ProductID,CoordX,CoordY) VALUES (:SiteID,:TimeStamp,:ProductID,:CoordX,:CoordY)");
$STH->execute($dbdata);
}
fclose($handle);
echo $row." rows inserted.";
}

使用 mysql_* 函数而不是 PDO 是理想的选择,因此我可以将这些值内爆到一个查询中(尽管很大)但不幸的是我需要遵守一些准则(PDO 到严格使用)。

我搜索了 SO,有非常相似的问题,但没有一个能解决我的问题。我尝试的是以下内容:

1- 运行 LOAD DATA INFILELOAD DATA LOCAL INFILE 查询,但不断收到“找不到文件”错误,尽管该文件确实存在并具有 777 权限。数据库服务器和共享主机帐户在不同的环境中。我尝试了 csv 文件的相对路径和 url 路径,但没有成功(在这两种情况下都找不到该文件)。

2- 我将 csv 文件分成 2 个文件并在每个文件上运行脚本,以查看脚本挂起的阈值,但对于每个文件,它在表中插入了两次条目。

我无权访问 php.ini,因为它是一个共享主机帐户(cloudsites)并且只能通过 phpMyAdmin 访问 MySQL

我还可以尝试什么来尽可能高效地完成此任务?

感谢任何帮助。

最佳答案

代码在我看来没有错。它挂起是因为它只需要一段时间来执行。你应该使用 phps set_time_limit以防止超时。

if (($handle = fopen($localCSV, "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
set_time_limit(30) // choose a value that works for you
// ... the rest of your script

不过,更好的方法是启动处理 csv 的后台进程,它需要某种锁定,因此它不会在多个实例中并行运行。如果您将状态写入磁盘上的文件,您可以轻松地将其呈现给您的用户。这同样适用于 cron 脚本(如果您可以使用托管解决方案做到这一点)

我觉得 PDO 的使用没问题。我不会考虑一次插入 csv 的所有行,但您也可以使用 PDO 一次插入多行。为多行创建语句和数据数组。它可能看起来像这个粗略的草图(我没有执行它所以可能会有一些错误):

function insert_data($DBH, array $dbdata, array $values) {
$sql = "INSERT INTO temp_csv (SiteID,TimeStamp,ProductID,CoordX,CoordY) VALUES %1$s;";
$STH = $DBH->prepare(sprintf($sql, join(', ', $values)));
$STH->execute($dbdata);
}

if (($handle = fopen($localCSV, "r")) !== FALSE) {
$dbdata = array();
$values = array();
$row = 0;
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
if(!count($dbdata))
$dbdata['SiteID'] = $siteID;

$dbdata['TimeStamp_'.$row] = $data[0];
$dbdata['ProductID_'.$row] = $data[1];
$dbdata['CoordX_'.$row] = $data[2];
$dbdata['CoordY_'.$row] = $data[3];
$values[] = sprintf('(:SiteID_%1$s,:TimeStamp_%1$s,:ProductID_%1$s,:CoordX_%1$s,:CoordY_%1$s)', $row);
$row++;

if($row % 10 === 0) {
set_time_limit(30);
insert_data($DBH, $dbdata, $values);
$values = array();
$dbdata = array();
}
}
// insert the rest
if(count($values))
insert_data($DBH, $dbdata, $values);
fclose($handle);
echo $row." rows inserted.";
}

至少读取 php.ini 配置的快捷方式是 phpinfo .查看 PHP 手册,很多配置值都可以在运行时从您的代码中设置。

关于PHP 将大型 CSV 文件导入 MySQL 表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20660767/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com