将CSV文件导入Postgre

时间:2015-06-13 02:32:03

标签: php postgresql csv

我正在编写一些PHP代码以将CSV文件导入Postgre数据库,我收到以下错误。你能救我吗?

  

警告:pg_end_copy():查询失败:错误:在数据中找到文字换行提示:使用" \ n"代表换行。背景:COPY t_translation,第21行C:\ xampp \ htdocs \ imports_csv \ importcsv.php中的第2行

<?php
$connString = 'host = localhost dbname= importdb user=postgres password=pgsql';
$db = pg_connect($connString);

$file = file('translation.csv');

//pg_exec($db, "CREATE TABLE t_translation (id numeric, identifier char(100), device char(10), page char(40), english char(100), date_created char(30), date_modified char(30), created_by char(30), modified_by char(30) )");
pg_exec($db, "COPY t_translation FROM stdin");


foreach ($file as $line) {

    $tmp = explode(",", $line);

    pg_put_line($db, sprintf("%d\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n", $tmp[0], $tmp[1], $tmp[2], $tmp[3], $tmp[4], $tmp[5], $tmp[6], $tmp[7], $tmp[8]));

}

pg_put_line($db, "\\.\n");
pg_end_copy($db);
?>

2 个答案:

答案 0 :(得分:2)

您需要在FILE_IGNORE_NEW_LINES函数中指定file()标志作为第二个参数,否则默认情况下将在每个数组项的末尾包含换行符。这可能是造成这个问题的原因。

所以只需添加此标志FILE_IGNORE_NEW_LINES,以便从csv文件中提取的行在每行的末尾不会有换行符:

$file = file('translation.csv', FILE_IGNORE_NEW_LINES);

我还建议使用fgetcsv()来读取csv文件。

答案 1 :(得分:0)

如果您愿意使用 PDO(需要单独的连接调用),那么有一个优雅的解决方案,它不需要 PHP 对数据进行大量处理,并且只要它们的字段的任何组合都可以使用它CSV 标头中的名称与数据库中的名称匹配。我假设您已经初始化了 PDO 并将对象设为 $pdo,文件名为 $filename。然后:

$file=fopen($filename,'r');
$lines=explode("\n", fread ($file, filesize($filename)));
if (end($lines)=='') array_pop($lines); // Remove the last line if it empty, as often happens, so it doesn't generate an error with postgres
$fields=array_shift($lines); // Retrieve & remove the field list
$null_as="\\\\N"; // Or whatever your notation for NULL is, if needed
$result=$pdo->pgsqlCopyFromArray('t_translation',$lines,',',$null_as,$fields);

这非常简单,除了 $result 返回成功或失败之外没有任何错误处理,但它可以作为一个起点。

我比您采用的方法更喜欢这个解决方案,因为您根本不需要指定字段,它都是自动处理的。

如果您不想使用 PDO,可以使用您的设置和语法提供类似的解决方案,只需将最后一行替换为:

pg_copy_from($db,'t_translation',$lines,',',$null_as)

但是这个方案并没有动态调整字段名,CSV 的字段需要与表中的字段完全匹配。但是,名称不需要对齐,因为忽略了 CSV 文件的第一行。我还没有测试最后一行,因为我不使用这种类型的连接,所以它可能有错误。