PG COPY错误:整数的输入语法无效

时间:2013-08-18 10:08:37

标签: postgresql csv import copy

正在运行COPY会导致 ERROR: invalid input syntax for integer: "" 错误消息。我错过了什么?

我的/tmp/people.csv文件:

"age","first_name","last_name"
"23","Ivan","Poupkine"
"","Eugene","Pirogov"

我的/tmp/csv_test.sql文件:

CREATE TABLE people (
  age        integer,
  first_name varchar(20),
  last_name  varchar(20)
);

COPY people
FROM '/tmp/people.csv'
WITH (
  FORMAT CSV,
  HEADER true,
  NULL ''
);

DROP TABLE people;

输出:

$ psql postgres -f /tmp/sql_test.sql
CREATE TABLE
psql:sql_test.sql:13: ERROR:  invalid input syntax for integer: ""
CONTEXT:  COPY people, line 3, column age: ""
DROP TABLE

花絮:

  • PostgreSQL 9.2.4

12 个答案:

答案 0 :(得分:23)

  

错误:整数的输入语法无效:“”

""不是有效整数。默认情况下,PostgreSQL在CSV中接受未加引号的空白字段为空,但""就像写:

SELECT ''::integer;

因同样的原因而失败。

如果你想处理像null整数的引用空字符串这样的CSV,你需要通过预处理器将它提供给PostgreSQL,这可能会让它稍微消失。 PostgreSQL的CSV输入并不能理解CSV的所有奇怪和奇妙的滥用行为。

选项包括:

  • 将其加载到电子表格中并导出纯正的CSV;
  • 使用Python csv模块,Perl Text::CSV等对其进行预处理;
  • 使用Perl / Python /无论加载CSV并将其直接插入数据库
  • 使用CloverETL,Talend Studio或Pentaho Kettle等ETL工具

答案 1 :(得分:8)

我认为最好更改你的csv文件,如:

"age","first_name","last_name"
23,Ivan,Poupkine
,Eugene,Pirogov

也可以像

一样定义你的表格
CREATE TABLE people (
  age        varchar(20),
  first_name varchar(20),
  last_name  varchar(20)
);

复制后,您可以转换空字符串:

select nullif(age, '')::int as age, first_name, last_name
from people

答案 2 :(得分:5)

我在带有.sql语句的postgres COPY文件中遇到同样的错误,但我的文件是制表符分隔而不是以逗号分隔和引用

我的错误是我急切地从github复制/粘贴了文件内容,但是在那个过程中所有选项卡都转换为空格,因此出错。我不得不下载并保存原始文件以获得好的副本。

答案 3 :(得分:5)

加载'|'时出现此错误虽然我的输入文件中没有'\ n''字符但已分隔的CSV文件。原来我忘了指定格式:

COPY ... FROM ... WITH( FORMAT CSV ,DELIMITER'|')。

答案 4 :(得分:2)

结束使用csvfix执行此操作:

csvfix map -fv '' -tv '0' /tmp/people.csv > /tmp/people_fixed.csv

如果您确定哪些列是integerfloat,您可以只指定它们:

csvfix map -f 1 -fv '' -tv '0' /tmp/people.csv > /tmp/people_fixed.csv

如果没有指定确切的列,可能会遇到明显的副作用,其中空白字符串将变为带有0字符的字符串。

答案 5 :(得分:2)

有一种方法可以解决“”,将引号的空字符串在整数列中作为空, 使用FORCE_NULL选项:

\copy table_name FROM 'file.csv' with (FORMAT CSV, FORCE_NULL(column_name));

请参见postgresql文档,https://www.postgresql.org/docs/current/static/sql-copy.html

答案 6 :(得分:1)

这应该在没有你修改源csv文件的情况下工作:

alter table people alter column age type text;
copy people from '/tmp/people.csv' with csv;

答案 7 :(得分:1)

CREATE TABLE people (
  first_name varchar(20),
  age        integer,
  last_name  varchar(20)
);

“名字”,“年龄”,“姓氏” 23岁的伊凡(Ivan) 尤金·比罗戈夫

使用{分隔符';',空'')复制'file.csv'中的人;

select * from people;

就在第一列.....

答案 8 :(得分:1)

只是在寻找解决方案时碰到了这一点,并且想补充一下,我能够通过在copy_from调用中添加“ null”参数来解决此问题:

cur.copy_from(f, tablename, sep=',', null='')

答案 9 :(得分:0)

使用以下命令在一行中从CSV复制数据,而无需强制转换和更改数据类型。 请用您的字符串替换“ NULL”,这会在复制数据中产生错误

copy table_name from 'path to csv file' (format csv, null "NULL", DELIMITER ',', HEADER);

答案 10 :(得分:0)

令人难以置信的是,我对相同错误的解决方案是重新排列列。对于执行上述解决方案但仍然无法克服错误的其他人。

显然,我不得不将CSV文件中的列排列为与PGADmin中表列表中的相同顺序匹配。

答案 11 :(得分:0)

全部使用python(使用df.groupby('year').max() ),首先创建一个空表,然后使用psycopg2将csv加载到其中。它应该处理空值。

copy_expert