Inserciones extrañas después de leer un CSV
Siguiendo con lo que os contaba en el post anterior, en otra ocasión tuve que importar un CSV, para lo cual disponemos del un módulo cojonudo con ese mismo nombre. Además de otras muchas cosas, nos permite leer y parsear un archivo con sólo escribir esto:
-
CSV::Reader.parse(file, ';') do |row|
-
# Cálculos, operaciones, mandangas varias…
-
end
Como veis, se trata de un bucle que saca una línea cada vez, permitiéndonos operar con ella como si de un array se tratase. Si en una de estas operaciones nos decidimos a insertar los datos directamente en la BBDD, podemos encontrarnos con el siguiente fallo:
-
RuntimeError: ERROR C22021 Minvalid byte sequence for encoding "UTF8": 0xe17271
-
HThis error can also happen if the byte sequence does not match the encoding expected by the server, which is controlled by "client_encoding".
-
F.\src\backend\utils\mb\wchar.c L1578
-
Rreport_invalid_encoding: INSERT INTO personas (nombre, apellido) VALUES('Pepito', 'Garc?a') RETURNING id
Si nos fijamos en los valores del “insert” que intentamos ejecutar, vemos que hay una interrogación (que en este caso se corresponde con una “í“). Esto se debe a que, al ser de texto plano, el archivo no cuenta con ninguna indicación que le permita al parser saber qué codificación tiene, por lo que debemos decírselo nosotros con una simple instrucción que nos brinda “Iconv“:
-
Iconv.conv('UTF-8', 'ISO-8859-15', campo)
Si conocemos el charset de entrada se lo podemos poner directamente (tal y como hemos hecho ahora). Sino, nos será de gran ayuda una librería como CharGuess, que se encarga de hacer diferentes comprobaciones para decirnos, finalmente, qué encoding cree que se ha encontrado. Es importante remarcar esto último, pues el resultado siempre será una mera conjetura de la aplicación, nunca una verdad absoluta.