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