我正在编写一些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);
?>
答案 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 文件的第一行。我还没有测试最后一行,因为我不使用这种类型的连接,所以它可能有错误。