2012-04-17 68 views
16
línea

Ejemplo CSV:COPIA postgresql y datos CSV w/comillas dobles

"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" 

Todos los valores después de "primero" son columnas numéricas. Muchos valores NULL simplemente citados como tales, a la derecha.

El intento de copiar:

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

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

Bueno, sí. Es un valor nulo. Intentará 2 a copiar:

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

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

Lo que un chico a hacer? Elimine todas las comillas dobles del archivo antes de ejecutar COPY? Puede hacer eso, pero pensé que hay una solución adecuada para lo que debe ser un problema increíblemente común.

+0

Parece que un error en PostgreSQL para mí (que todavía está allí en 9.4) porque 'nulo ''' debe tratar a vacío cadenas como nulas. – Tobia

Respuesta

8

Mientras que algunos productos de bases de datos tratan una cadena vacía como un valor NULO, el estándar dice que son distintos, y PostgreSQL los trata como distintos.

Sería mejor si pudiera generar su archivo CSV con una representación inequívoca. Mientras que podría usar sed o algo para filtrar el archivo a un buen formato, la otra opción sería COPY los datos en una tabla donde una columna text podría aceptar las cadenas vacías y luego llenar la tabla de destino. La función NULLIF puede ayudar con eso: http://www.postgresql.org/docs/9.1/interactive/functions-conditional.html#FUNCTIONS-NULLIF - devolverá NULL si ambos argumentos coinciden y el primer valor si no lo hacen. Por lo tanto, algo como NULLIF(txtcol, '')::numeric podría funcionar para usted.

+0

Genial: puedo crear fácilmente el archivo CSV sin comillas dobles, pero, amigo, no estoy seguro de que haya algo menos ambiguo que un texto vacío entre comillas dobles. Sin embargo, soy yo. – Wells

+2

@Wells: según la especificación SQL, puede tener una cadena de caracteres de longitud cero, y eso no es lo mismo que 'NULL'. Sé que hay bases de datos que las tratan como diferentes deletreos de la misma cosa, y si solo has trabajado con productos que lo hacen puede parecer natural, pero lógicamente es la diferencia entre saber que el valor es una cadena de longitud cero y no saber el valor. – kgrittn

+0

De acuerdo, pero la columna es numérica en la base de datos, por lo que no estoy seguro de por qué COPY debería preocuparse por tratar el valor CSV como una cadena de caracteres. – Wells

7

como alternativa, usando

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

funciona tan bien.

+2

Excelente idea, pero creo que 's /," "/, \\ N/g'' sería más adecuado. (\ N es la representación de NULLs) – wildplasser

+0

'con csv' implica' nulo '' '(cadena vacía = nulo) – wrschneider

1

Creo que todo lo que tiene que hacer aquí es la siguiente:

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

Creo que se vería mejor en un bloque de código – demongolem

+1

Lamentablemente no. En PSQL 9.3 'QUOTE' obtiene un error de sintaxis y' NULL '' 'no convierte las cadenas vacías a NULL. –

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