Erreur de copie PG: syntaxe d'entrée invalide pour l'entier

L'Exécution de COPY résultats dans ERROR: invalid input syntax for integer: "" message d'erreur pour moi. Ce qui me manque?

Mon fichier /tmp/people.csv:

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

Mon fichier /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;

Sortie:

$ 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
31
demandé sur gmile 2013-08-18 14:08:36

7 réponses

Erreur: syntaxe d'entrée invalide pour entier: ""

"" n'est pas un entier valide. PostgreSQL accepte unquoted champs vides comme null par défaut dans CSV, mais "" serait comme écrire:

SELECT ''::integer;

Et échouent pour la même raison.

Si vous voulez traiter avec CSV qui a des choses comme des chaînes vides entre guillemets pour des entiers Nuls, vous devrez le nourrir à PostgreSQL via un pré-processeur qui peut le nettoyer un peu. L'entrée CSV de PostgreSQL ne comprend pas tout les abus possibles étranges et merveilleux de CSV.

Les Options incluent:

  • le charger dans une feuille de calcul et exporter sane CSV;
  • en utilisant le module Python csv, Perl Text::CSV, etc pour le pré-traiter;
  • en utilisant Perl / Python / whatever pour charger le CSV et l'insérer directement dans la base de données
  • utiliser un outil ETL comme CloverETL, Talend Studio ou Pentaho Kettle
21
répondu Craig Ringer 2013-08-18 10:57:21

Je pense qu'il est préférable de changer votre fichier csv comme:

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

Il est également possible de définir votre table comme

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

Et après la copie, vous pouvez convertir des chaînes vides:

select nullif(age, '')::int as age, first_name, last_name
from people
8
répondu Roman Pekar 2013-08-18 11:04:20

J'ai eu cette même erreur sur un fichier postgres .sql avec une instruction COPY, mais mon fichier était séparé par tabulation au lieu de séparé par des virgules et entre guillemets.

Mon erreur était que j'ai copié/collé avec impatience le contenu du fichier à partir de github, mais dans ce processus, tous les onglets ont été convertis en espaces, d'où l'erreur. J'ai dû télécharger et enregistrer le fichier raw pour obtenir une bonne copie.

5
répondu zwippie 2015-08-31 15:02:42

A fini par le faire en utilisant csvfix:

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

Si vous savez avec certitude quelles colonnes devaient être integer ou float, Vous pouvez les spécifier uniquement:

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

Sans spécifier les colonnes exactes, on peut éprouver un effet secondaire évident, où une chaîne vide sera transformée en une chaîne avec un caractère 0.

2
répondu gmile 2016-08-30 09:59:18

Cela devrait fonctionner sans que vous modifiiez le fichier csv source:

alter table people alter column age type text;
copy people from '/tmp/people.csv' with csv;
1
répondu soyayix 2018-01-08 18:19:29

J'ai eu cette erreur lors du chargement du fichier CSV séparé '|' bien qu'il n'y ait pas de caractères '"' dans mon fichier d'entrée. Il s'est avéré que j'ai oublié de spécifier le FORMAT:

Copier ... DE ... AVEC (FORMAT CSV, DÉLIMITEUR '|').

1
répondu Slobodan Savkovic 2018-03-11 00:09:43

Il existe un moyen de résoudre"", la chaîne nulle entre guillemets comme null dans la colonne entière, utiliser L'option FORCE_NULL:

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

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

1
répondu Charlie 木匠 2018-10-01 22:14:43