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
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, PerlText::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
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
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.
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.
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;
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 '|').
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