2012-04-17 10 views
16

Beispiel CSV-Zeile:postgresql COPY und CSV-Daten w/doppelte Anführungszeichen

"2012","Test User","ABC","First","71.0","","","0","0","3","3","0","0","","0","","","","","0.1","","4.0","0.1","4.2","80.8","847" 

Alle Werte nach "First" sind numerische Spalten. Viele NULL-Werte als solche zitiert, richtig.

Versuch COPY:

copy mytable from 'myfile.csv' with csv header quote '"'; 

NOPE: ERROR: invalid input syntax for type numeric: ""

Nun, ja. Es ist ein Nullwert. Versuch 2 bei COPY:

copy mytable from 'myfile.csv' with csv header quote '"' null '""'; 

NOPE: ERROR: CSV quote character must not appear in the NULL specification

Was ist ein Kerl zu tun? Entfernen Sie alle doppelten Anführungszeichen aus der Datei, bevor Sie COPY ausführen? Kann das tun, aber ich dachte mir, es gibt eine richtige Lösung für das, was ein unglaublich häufiges Problem sein muss.

+0

Sieht aus wie ein Fehler in PostgreSQL mir (was in 9.4 noch da ist), weil 'null‚‘' sollte leer behandeln Zeichenfolgen als null. – Tobia

Antwort

8

Während einige Datenbankprodukte eine leere Zeichenfolge als NULL-Wert behandeln, gibt der Standard an, dass sie unterschiedlich sind, und PostgreSQL behandelt sie als unterschiedlich.

Es wäre am besten, wenn Sie Ihre CSV-Datei mit einer eindeutigen Darstellung generieren könnten. Während Sie könnte verwenden Sie sed oder etwas, um die Datei zu einem guten Format zu filtern, wäre die andere Option COPY die Daten in eine Tabelle, wo eine text Spalte die leeren Zeichenfolgen akzeptieren konnte, und dann die Zieltabelle auffüllen. Die NULLIF Funktion kann dabei helfen: http://www.postgresql.org/docs/9.1/interactive/functions-conditional.html#FUNCTIONS-NULLIF - es wird NULL zurückgeben, wenn beide Argumente übereinstimmen und der erste Wert, wenn sie nicht übereinstimmen. So könnte etwas wie NULLIF(txtcol, '')::numeric für Sie arbeiten.

+0

Cool- Ich kann die CSV ohne Anführungszeichen leicht erstellen, aber Mann, ich bin mir nicht sicher, dass es etwas weniger Zweideutiges als eine leere Zeichenfolge in doppelten Anführungszeichen gibt. Das bin nur ich. – Wells

+2

@Wells: Nach der SQL-Spezifikation können Sie eine Zeichenkette der Länge Null haben, und das ist nicht das Gleiche wie 'NULL'. Ich weiß, dass es Datenbanken gibt, die sie als unterschiedliche Schreibweisen derselben Sache behandeln, und wenn Sie nur mit Produkten gearbeitet haben, die es natürlich erscheinen lassen, aber logisch ist der Unterschied zwischen dem Wissen, dass der Wert eine Länge Null ist und nicht wissen der Wert. – kgrittn

+0

Einverstanden, aber die Spalte ist numerisch in der Datenbank, deshalb bin ich mir nicht sicher, warum die COPY sich darum kümmern sollte, den CSV-Wert als Zeichenkette zu behandeln. – Wells

7

als Alternative, funktioniert auch

sed 's/""//g' myfile.csv > myfile-formatted.csv 
psql 
# copy mytable from 'myfile-formatted.csv' with csv header; 

verwenden.

+2

Ausgezeichnete Idee, aber ich denke 's /," "/, \\ N/g'' wäre besser geeignet. (\ N ist die Darstellung für NULL) – wildplasser

+0

'mit csv' impliziert' null '' '(leere Zeichenkette = null) – wrschneider

1

Ich glaube, alles, was Sie hier tun müssen, ist die folgende:

COPY mytable from '/dir/myfile.csv' DELIMITER ',' NULL '' WITH CSV HEADER QUOTE ; 
+0

Ich denke, das würde in einem Codeblock besser aussehen – demongolem

+1

Leider nicht. Auf PSQL 9.3 '' QUOTE' wird ein Syntaxfehler und 'NULL' ''konvertiert die leeren Zeichenfolgen nicht zu NULL. –

1
COPY mytable from '/dir/myfile.csv' DELIMITER ',' NULL '' 
WITH CSV HEADER FORCE QUOTE *; 
Verwandte Themen