PG COPY error: invalid input syntax for integer

2020-02-23 04:50发布

Running COPY results in ERROR: invalid input syntax for integer: "" error message for me. What am I missing?

My /tmp/people.csv file:

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

My /tmp/csv_test.sql file:

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;

Output:

$ 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

Trivia:

  • PostgreSQL 9.2.4

10条回答
在下西门庆
2楼-- · 2020-02-23 05:23

There is a way to solve "", the quoted null string as null in integer column, use FORCE_NULL option :

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

see postgresql document, https://www.postgresql.org/docs/current/static/sql-copy.html

查看更多
何必那么认真
3楼-- · 2020-02-23 05:26

Ended up doing this using csvfix:

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

In case you know for sure which columns were meant to be integer or float, you can specify just them:

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

Without specifying the exact columns, one may experience an obvious side-effect, where a blank string will be turned into a string with a 0 character.

查看更多
相关推荐>>
4楼-- · 2020-02-23 05:28
CREATE TABLE people (
  first_name varchar(20),
  age        integer,
  last_name  varchar(20)
);

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

copy people from 'file.csv' with (delimiter ';', null '');

select * from people;

Just in first column.....

查看更多
你好瞎i
5楼-- · 2020-02-23 05:32

ERROR: invalid input syntax for integer: ""

"" isn't a valid integer. PostgreSQL accepts unquoted blank fields as null by default in CSV, but "" would be like writing:

SELECT ''::integer;

and fail for the same reason.

If you want to deal with CSV that has things like quoted empty strings for null integers, you'll need to feed it to PostgreSQL via a pre-processor that can neaten it up a bit. PostgreSQL's CSV input doesn't understand all the weird and wonderful possible abuses of CSV.

Options include:

  • Loading it in a spreadsheet and exporting sane CSV;
  • Using the Python csv module, Perl Text::CSV, etc to pre-process it;
  • Using Perl/Python/whatever to load the CSV and insert it directly into the DB
  • Using an ETL tool like CloverETL, Talend Studio, or Pentaho Kettle
查看更多
成全新的幸福
6楼-- · 2020-02-23 05:32

I think it's better to change your csv file like:

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

It's also possible to define your table like

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

and after copy, you can convert empty strings:

select nullif(age, '')::int as age, first_name, last_name
from people
查看更多
手持菜刀,她持情操
7楼-- · 2020-02-23 05:33

this ought to work without you modifying the source csv file:

alter table people alter column age type text;
copy people from '/tmp/people.csv' with csv;
查看更多
登录 后发表回答