如何将一个较大的csv文件拆分为多个csv文件

时间:2018-08-21 14:09:01

标签: php csv

我们从openstreetmaps gis数据下载了.osm文件,并通过osmconvert.exe将其转换为.csv文件。 csv文件的大小为3.5 GB。我们尝试通过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);
    }
    // this you'll have to expand
    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错误和超时。我们将memory_limit更改为4000MB,并将时间限制设置为0。然后再次尝试该脚本,页面为空白,并不断尝试执行该脚本,但未在表中插入一行。

经历了所有这些之后,我们认为前进的唯一方法是将csv文件拆分为多个文件。

我们该怎么做。

预先感谢

2 个答案:

答案 0 :(得分:0)

如果您正在寻找特定于PHP的解决方案;这是一个可以根据需要进行调整的简单方法。好的,此解决方案假定您不需要为每个文件重复标题行。您可以相应地对其进行修改,以便在需要时为每个零件文件添加标题行:

$outputFile = 'indiacountry-part-';
$splitSize = 50000; // 50k records in a one file
$in = fopen('indiacountry.csv', 'r');

$rows = 0;
$fileCount = 1;
$out = null;

while (!feof($in)) {
    if (($rows % $splitSize) == 0) {
        if ($rows > 0) {
            fclose($out);
        }

        $fileCount++;

        // for filenames like indiacountry-part-0001.csv, indiacountry-part-0002.csv etc
        $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。

答案 1 :(得分:0)

您显示的脚本正在将整个.csv文件读入内存阵列中。毫不奇怪,它将至少需要3.5gig +的内存才能运行。

取而代之的是从文件中读取一行并将其直接应用于数据库。

  

我现在将忽略您正在使用旧的,危险且已弃用的mysql_数据库扩展这一事实。如果您告诉我您可以访问mysqli_PDO,我将为其中一个API重写

$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";