将CSV文件导入到PostgreSQL

5

我正在编写一些PHP代码将CSV文件导入到Postgre数据库中,但是我遇到了下面的错误。你能帮助我吗?

警告:pg_end_copy():查询失败:ERROR:在数据中找到文字换行符 HINT:使用“\n”表示换行符。CONTEXT:COPY t_translation,line 2 in C:\xampp\htdocs\importing_csv\importcsv.php on line 21

<?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个回答

3
您需要在file()函数中指定FILE_IGNORE_NEW_LINES标志作为第二个参数,否则默认情况下将包括每个数组项末尾的换行符。这很可能是导致此处问题的原因。
因此,只需添加此标志FILE_IGNORE_NEW_LINES,以便从csv文件中提取的行不会在每行末尾具有换行符:
$file = file('translation.csv', FILE_IGNORE_NEW_LINES);

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

1
不错,我不知道那个标记。我刚想建议使用$tmp = explode(",", trim($line));,但这看起来更好。 - mike.k

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文件的第一行将被忽略。我还没有测试过最后一行,因为我不使用这种类型的连接,所以可能会出现错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接