【问题标题】:Exporting data containing line feeds as CSV from PostgreSQL从 PostgreSQL 将包含换行符的数据导出为 CSV
【发布时间】:2018-09-04 06:40:07
【问题描述】:

我正在尝试将数据从 postgresql 导出到 csv。

首先我创建了查询并尝试使用文件从 pgadmin 导出 -> 导出到 CSV。 CSV 是错误的,因为它包含例如:

标题:Field1;Field2;Field3;Field4

现在,行开始良好,除了将其放在另一行的最后一个字段:

例子:

数据1;数据2;数据3;

数据4;

问题是我尝试将数据导入另一台服务器时出错。

数据来自我创建的视图。

我也试过了

COPY view(field1,field2...) TO 'C:\test.csv' DELIMITER ',' CSV HEADER;

它导出相同的文件。

我只想将数据导出到另一台服务器。

编辑:

尝试导入 csv 时出现错误:

错误:最后一个预期列之后的额外数据。上下文复制 动作,第 3 行:>

所以第一行是表头,第二行是第一行数据减去最后一个字段,单独在第三行。

【问题讨论】:

  • 导出的 csv 在另一行中有最后一个字段,当我尝试在另一台服务器上导入它时会出错。
  • 引用你得到的命令和异常
  • 请一行生成的csv在它停止的地方)或更好的三行(带环绕)
  • 从错误中我假设您尝试“导入”数据的表中的列较少。请给我们两张表的 DDL(导出一张和导入一张)
  • @AlexE。为了让其他用户更好地找到您的问题,请考虑将标题更改为更明确的内容,例如"将包含换行符的数据作为 CSV 从 PostgreSQL 导出到远程服务器"

标签: sql postgresql csv view export


【解决方案1】:

为了让您将文件导出到另一台服务器,您有两种选择:

  • 在两台服务器之间创建共享文件夹,以便 数据库也可以访问此目录。

COPY (SELECT field1,field2 FROM your_table) TO '[shared directory]' DELIMITER ',' CSV HEADER;

  • 使用STDOUT 触发从目标服务器导出 COPY。使用psql,您可以通过以下方式实现此目的 命令:

psql yourdb -c "COPY (SELECT * FROM your_table) TO STDOUT" > output.csv

编辑:解决包含换行符的字段问题 (\n)

如果您想摆脱换行符,请使用 REPLACE 函数。

例子:

 SELECT E'foo\nbar';
 ?column? 
----------
 foo     +
 bar
(1 Zeile)

删除换行符:

SELECT REPLACE(E'foo\nbaar',E'\n','');
 replace 
---------
 foobaar
(1 Zeile)

所以你的COPY 应该是这样的:

COPY (SELECT field1,REPLACE(field2,E'\n','') AS field2 FROM your_table) TO '[shared directory]' DELIMITER ',' CSV HEADER;

【讨论】:

  • 就像我在操作中所说的那样,我尝试了 Copy 命令,虽然它有效,但它创建的 csv 的错误是最后一个字段位于新行中,这在尝试时会出错进口。
  • 您可以编辑您的问题以显示错误消息吗?通常使用引号(甚至可能是FORCE QUOTE?)可以避免包含换行符的字段出现错误。
  • 你能尝试这样的事情并告诉我们吗? COPY (SELECT field1,field2) TO '/tmp/copy_test.csv' WITH CSV FORCE QUOTE field2; 。考虑到field2 是有问题的。
  • 我刚刚在查询中添加了 2 个字段,现在我有一个包含最后 3 个字段的新行。
  • 您的字段是否可能包含换行符?我的意思是,即使他们这样做了,postgres 也应该生成一个有效的 csv 文件。
【解决方案2】:

上面描述的导出过程是可以的,例如:

t=# create table so(i int, t text);
CREATE TABLE
t=# insert into so select 1,chr(10)||'aaa';
INSERT 0 1
t=# copy so to stdout csv header;
i,t
1,"
aaa"
t=# create table so1(i int, t text);
CREATE TABLE
t=# copy so1 from stdout csv header;
Enter data to be copied followed by a newline.
End with a backslash and a period on a line by itself, or an EOF signal.
>> i,t
1,"
aaa"
>> >> >> \.
COPY 1
t=# select * from so1;
 i |  t
---+-----
 1 |    +
   | aaa
(1 row)

【讨论】:

  • 你能解释一下这到底是做什么的吗?这对我来说太高级了。
猜你喜欢
  • 2011-01-16
  • 2021-10-12
  • 2012-02-10
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-02
  • 1970-01-01
相关资源
最近更新 更多