如何将一个大的csv文件拆分成多个csv文件
如何将一个大的csv文件拆分成多个csv文件
我们从OpenStreetMaps的GIS数据中下载了.osm文件,并通过osmconvert.exe将其转换为.csv文件。这个csv文件的大小为3.5GB。我们尝试使用heidisql将其导入数据库。还尝试使用以下php脚本将文件导入数据库:
$path = "../../indiacountry.csv"; $row = 0; if (($handle = fopen($path, "r")) !== FALSE) { while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { $row++; $data_entries[] = $data ; } fclose($handle); } // 这部分需要扩展 foreach($data_entries as $line){ $ts++; if ($ts>0) { $ft++; if(mysql_query("insert into mbrace_resources.street_unit_number_india(id1) values ('".str_replace ("'","",$line [0])."')") or die("the eror ".mysql_error())); } // $db->execute($line); }
当我们首次尝试运行这个脚本时,出现了内存限制错误和超时。我们将memory_limit更改为4000MB,并将时间限制设置为0。然后再次尝试运行脚本,页面是空白的,并且不断尝试执行脚本,但没有一行数据被插入到表中。
在经历了所有这些之后,我们觉得唯一的解决办法是将csv文件拆分成多个文件。
我们应该如何操作呢?
提前感谢您的帮助。
如何将一个大的csv文件拆分成多个csv文件
当我们尝试运行这个脚本时,它将整个.csv文件读入内存数组。不奇怪,它无法运行,因为这将需要至少3.5GB的内存。相反,我们可以一次从文件中读取一行,并直接应用于数据库。
以下是一个示例脚本:
$path = "../../indiacountry.csv"; $row = 0; if (($handle = fopen($path, "r")) !== FALSE) { while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { $row++; $id = str_replace ("'","",$line [0]); mysql_query("insert into mbrace_resources.street_unit_number_india (id1) values ('$id')") or die("the eror ".mysql_error()); } fclose($handle); } echo "Finished: Added $row rows";
感谢Riggsfolly的建议,脚本可以正常工作。关于mysql,我们知道它已经过时了。但问题是,我们已经在过去的几年中使用mysql编写了整个应用程序。将其转换为mysqli或pdo需要一些工作。我们将尽快将脚本转换为mysqli。再次感谢关心。
如何将一个大型CSV文件分割成多个CSV文件
如果您正在寻找PHP特定的解决方案;这里有一个简单的可以根据您的需求进行调整的解决方案。这个解决方案假设您不需要为每个文件重复添加标题行。如果需要,您可以相应地修改它以在每个部分文件中添加标题行。
$outputFile = 'indiacountry-part-';
$splitSize = 50000; // 一个文件中的50k条记录
$in = fopen('indiacountry.csv', 'r');
$rows = 0;
$fileCount = 1;
$out = null;
while (!feof($in)) {
if (($rows % $splitSize) == 0) {
if ($rows > 0) {
fclose($out);
}
$fileCount++;
// 用于文件名,如indiacountry-part-0001.csv,indiacountry-part-0002.csv等
$fileCounterDisplay = sprintf("%04d", $fileCount);
$fileName = "$outputFile$fileCounterDisplay.csv";
$out = fopen($fileName, 'w');
}
$data = fgetcsv($in);
if ($data)
fputcsv($out, $data);
$rows++;
}
fclose($out);
现在,您可以以编程方式解析每个部分文件'indiacountry-part-xxxx.csv'并将其分批插入到您的表中。在读取每一行时,将其插入,而不是作为CLOB插入。
尝试了您的脚本,但是脚本一直加载。原因很简单,文件大小为3.5GB。
我同意!显然,这种组合(PHP、大数据集、线性提取等)是缓慢和迟缓的。我只给出答案是因为您正在尝试在PHP中修复这个问题。然而,也可以尝试其他语言。逻辑基本上是相同的。Unix shell脚本也可以处理这个问题。此外,还可以寻找通常具有CSV导入功能并且设计良好以执行此类批量插入的SQL客户端。例如:HeidiSQL。祝好!
我不使用PHPmyadmin,请注意。Heidisql是我的SQL客户端多年来一直使用的工具。即使那个也给我“无响应错误”。