Подтвердить что ты не робот

Ошибка PG 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
4b9b3361

Ответ 1

ОШИБКА: неверный синтаксис ввода для целого: ""

"" не является допустимым целым числом. PostgreSQL принимает неучтенные пустые поля как null по умолчанию в CSV, но "" будет похож на запись:

SELECT ''::integer;

и сбой по той же причине.

Если вы хотите иметь дело с CSV, который имеет такие вещи, как процитированные пустые строки для нулевых целых чисел, вам нужно будет отправить его в PostgreSQL через предварительный процессор, который может немного его поднять. PostgreSQL CSV вход не понимает всех странных и замечательных возможных злоупотреблений CSV.

Параметры включают:

  • Загрузка его в электронную таблицу и экспорт нормального CSV;
  • Использование модуля Python csv, Perl Text::CSV и т.д. для его предварительной обработки;
  • Использование Perl/Python/что угодно для загрузки CSV и вставки его непосредственно в DB
  • Использование инструмента ETL, такого как CloverETL, Talend Studio или Pentaho Kettle.

Ответ 2

Я думаю, что лучше изменить файл 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

Ответ 3

У меня была такая же ошибка в файле postgres .sql с инструкцией COPY, но мой файл был разделен на разделы, а не разделен запятыми и кавычками.

Моя ошибка заключалась в том, что я с готовностью копировал/вставлял содержимое файла из github, но в этом процессе все вкладки были преобразованы в пробелы, следовательно, ошибка. Мне пришлось загрузить и сохранить исходный файл, чтобы получить хорошую копию.

Ответ 4

Я получил эту ошибку при загрузке '|' если в моем исходном файле не было символов '' '. Оказалось, что я забыл указать FORMAT:

COPY... FROM... WITH ( ФОРМАТ CSV, DELIMITER '|').

Ответ 5

Закончено делать это с помощью csvfix:

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

Если вы точно знаете, какие столбцы должны были быть integer или float, вы можете указать только их:

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

Без указания точных столбцов может возникнуть очевидный побочный эффект, когда пустая строка будет преобразована в строку с символом 0.

Ответ 6

Есть способ решить "", заключенная в кавычки пустая строка как ноль в целочисленном столбце, используйте параметр 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

Ответ 7

это должно работать без изменения исходного файла csv:

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

Ответ 8

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

"first_name", "возраст", "last_name" Иван, 23, Poupkine Евгений Пирогов ,

скопировать людей из 'file.csv' с помощью (разделителя ';', null '');

select * from people;

Просто в первом столбце.....

Ответ 9

Просто наткнулся на это, когда искал решение, и хотел добавить, что мне удалось решить эту проблему, добавив параметр "null" в вызов copy_from:

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