Hoy, encontramos un error al intentar crear algunas semillas de base de datos a partir de un CSV. Este CSV fue generado originalmente por mí usando un script Ruby que canalizó la salida a un archivo y se guardó como CSV.
El CSV se registró en Git y se usó durante un tiempo hasta que tuvimos que actualizar algunas partes agregando una nueva columna y arreglando algunos valores.
Si bien aún no sabemos la razón exacta, mi teoría es que, de alguna manera, Excel para Mac (todos usamos Mac) agregó algunos metadatos adicionales incluso después de guardar el archivo como CSV.
Esto, a su vez, hizo que cualquiera que usara la semilla recibiera el siguiente error:
CSV::MalformedCSVError: Illegal quoting in line 1.
Abrí el archivo CSV y nada parecía sospechoso. Mi primer pensamiento fue unas comillas izquierda / derecha se mezclaron de alguna manera en el archivo en lugar de sólo las comillas dobles 'normales': "
. Pero luego de una investigación más profunda, no hubo nada fuera de lo común. Esto me llevó a borrar todo el archivo y volver a escribir la primera fila.
Guardé ese archivo nuevamente y ejecuté la migración:
CSV::MalformedCSVError: Illegal quoting in line 1.
¡¿Qué?!
Bien, esto me estaba volviendo loco. Abrí un nuevo archivo, volví a escribir exactamente la línea única y ejecuté la migración. Funcionó. Entonces, ¿qué había en ese archivo?
Sólo hay una forma de averiguarlo:
cat companies.csv | pbcopy | pbpaste > temp.csv rm companies.csv mv temp.csv companies.csv git diff
Entonces OSX tiene estas dos funciones que son muy útiles: pbcopy
y pbpaste
. Básicamente, todo lo que se canaliza pbcopy
entra en su portapapeles y pbpaste
coloca lo que tiene en su portapapeles en la salida estándar (stdout). Pero elimina todo el formato.
Muy útil cuando solo desea copiar algún texto de algún lugar y desea pegarlo en un editor WYSIWYG sin todo el formato. Como cuando escribe un correo electrónico desde Gmail, por ejemplo.
Luego eliminé el archivo original y guardé el nuevo archivo 'sin formato' con el mismo nombre de archivo para poder ver la diferencia.
Y finalmente vimos al hombre invisible:


Una búsqueda rápida en Google nos dijo que nuestro amigo U+FEFF
se llamaba ZERO WIDTH NO-BREAK SPACE
. Además, un viaje rápido a Wikipedia nos informó sobre los usos reales de U+FEFF
, más comúnmente conocido como Byte order mark
o BOM
.
Nuestro amigo FEFF
significa cosas diferentes, pero básicamente es una señal para un programa sobre cómo leer el texto. Puede ser UTF-8
(más común) UTF-16
, o incluso UTF-32
.
FEFF
sí mismo es para UTF-16
- en UTF-8
él se conoce más comúnmente como 0xEF,0xBB, or 0xBF
.
Desde mi entender, cuando el archivo CSV se abre en Excel y se guarda, Excel crea un espacio para nuestro polizón invisible U+FEFF
. ¡Y delante del archivo para arrancar!
Excel hizo algo de magia, y probablemente se guardó en UTF-16
lugar de UTF-8
. UTF-8
no lo entiende BOM
y simplemente lo trata como un no carácter, así que visualmente el archivo estaba bien. Pero Ruby CSV
idea de que había algo malo, ya que supone el archivo que estaba leyendo era UTF-8
y no podía pasar por alto el señor U+FEFF
.
Entonces, lección aprendida: no abra (¡y guarde!) Un archivo CSV en Excel si desea alimentarlo al CSV
analizador de Ruby .
Si alguna vez encuentra un error como ese, asegúrese de buscar caracteres ocultos que su editor no muestre. Si aún no puede verlo y está usando OSX, entonces pbcopy
y pbpaste
lo ayudarán: eliminan cualquier formato o caracteres ocultos del texto, además de copiarlo y pegarlo.