2012-10-13 196 views
26

Estoy atascado tratando de obtener texto UTF-8 en una base de datos MySQL desde R. Estoy ejecutando R en OS X (intenté ambos a través de la GUI y la línea de comandos), donde la configuración regional predeterminada es en_US.UTF-8, y no importa lo que intento, el resultado de la consulta muestra "?" para todos los caracteres que no sean ASCII.Obteniendo texto UTF-8 de MySQL en R devuelve "????"

He tratado de establecer options(encoding='UTF-8'), DBMSencoding='UTF-8' cuando se conecta a través de ODBC, configurar Encoding(res$str) <- 'UTF-8' después de ir a buscar los resultados, así como las variantes 'utf8' de cada uno de ellos, todo fue en vano. Al ejecutar la consulta desde la línea de comandos, el cliente de mysql muestra los resultados correctamente.

Estoy totalmente perplejo. ¿Alguna idea de por qué no está funcionando u otras cosas que debería probar?

Aquí es un caso de prueba bastante mínima:

$ mysql -u root 
mysql> CREATE DATABASE test; 
mysql> USE test; 
mysql> CREATE TABLE test (str VARCHAR(10)) ENGINE=InnoDB DEFAULT CHARSET=utf8; 
Query OK, 0 rows affected (0.02 sec) 

mysql> INSERT INTO test (str) VALUES ('こんにちは'); 
Query OK, 1 row affected (0.00 sec) 

mysql> select * from test; 
+-----------------+ 
| str    | 
+-----------------+ 
| こんにちは  | 
+-----------------+ 
1 row in set (0.00 sec) 

consultar la tabla en I usando ambos espectáculos RODBC y RMySQL "?????" para la columna de str:

> con <- odbcDriverConnect('DRIVER=mysql;user=root', DBMSencoding='UTF-8') 
> sqlQuery(con, 'SELECT * FROM rtest.test') 
    str 
1 ????? 
> library(RMySQL) 
Loading required package: DBI 
> con <- dbConnect(MySQL(), user='root') 
> dbGetQuery(con, 'SELECT * FROM rtest.test') 
    str 
1 ????? 

Para completar, aquí está mi sessionInfo:

> sessionInfo() 
R version 2.15.1 (2012-06-22) 
Platform: x86_64-apple-darwin9.8.0/x86_64 (64-bit) 

locale: 
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8 

attached base packages: 
[1] stats  graphics grDevices utils  datasets methods base  

other attached packages: 
[1] RMySQL_0.9-3 DBI_0.2-5 RODBC_1.3-6 

Respuesta

26

Gracias a @chooban descubrí que la sesión de conexión estaba usando latin1 en lugar de utf8. Aquí hay dos soluciones que encontré:

  • Para RMySQL, después de conectar ejecute la consulta SET NAMES utf8 para cambiar el conjunto de caracteres de conexión.
  • Para RODBC, conéctese usando CharSet=utf8 en la cadena DSN. No pude ejecutar SET NAMES a través de ODBC.

This question me orientaron en la dirección correcta.

5

Aquí hay algo que probar al menos. Después de que se haya conectado, ejecute "MOSTRAR VARIABLES COMO 'character_set_%'" e imprima los resultados. Si no hay nada más, es una verificación útil para ver si las opciones de conjunto de caracteres que ha especificado han tomado.

+0

Buena llamada. Efectivamente, todas las variables del juego de caracteres relevantes muestran "latin1". Encontré una solución que publicaré por separado. –

0

Esto funcionó para mí. Aquí hay un ejemplo completo:

con = dbConnect(drv = MySQL(), user = user, password = password, 
       dbname = dbname, host=host) 

dbSendQuery(con, "SET NAMES utf8mb4;") 
dbSendQuery(con, "SET CHARACTER SET utf8mb4;") 
dbSendQuery(con, "SET character_set_connection=utf8mb4;") 


dbGetQuery(con, "SELECT * FROM WHATEVER")