Windows上的RMySQL编码问题 - 西班牙语字符ñ

时间:2017-03-29 10:48:00

标签: mysql r encoding utf-8

在R中使用RMySQL :: dbWriteTable函数在Windows上将表写入MySQL时,我收到有关字符[ñ]的错误消息。

简化的例子是:

    table <- data.frame(a=seq(1:3), b=c("És", "España", "Compañía"))
    table

 a        b
1 1       És
2 2   España
3 3 Compañía


db <- dbConnect(MySQL(), user = "####", password = "####", dbname ="test", host= "localhost")

RMySQL::dbWriteTable(db, name="test1", table, overwrite=T, append=F )

Error in .local(conn, statement, ...) : 
  could not run statement: Invalid utf8 character string: 'Espa'

正如您所看到的,重音符号(“És”)没有问题,但有ñ字符(“España”)。

另一方面,MySQL没有问题,因为这个查询工作正常:

INSERT INTO test.test1 (a,b)
values (1, "España");

我之前已经尝试过写表的事情:

  1. 为所有表格编码(x)&lt; - “UTF-8”。

  2. 所有表格的
  3. iconv(x,“UTF-8”,“UTF-8”)。

  4. 发送预查询:dbSendQuery(db,“SET NAMES UTF8;”)

  5. 将MySQL表校对更改为:“utf-8-general,latin-1,latin-1-spanish ...”

  6. *尝试过“Latin-1”编码,但也无法正常工作。

    我一直在寻找这个问题的答案一段时间没有运气 请帮忙!

    版本:

    MySQL 5.7.17

    R版本3.3.0

    Sys.getlocale()

    [1] "LC_COLLATE=English_United States.1252;LC_CTYPE=English_United States.1252;LC_MONETARY=English_United States.1252;LC_NUMERIC=C;LC_TIME=C"
    

    PS:在Linux环境中运行良好但我在当前项目中遇到了Windows :(

4 个答案:

答案 0 :(得分:0)

这适用于Windows:

write.csv(table, file = "tmp.csv", fileEncoding = "utf8", quote = FALSE, row.names = FALSE)

db <- dbConnect(MySQL(), user = "####", password = "####", dbname ="test", host= "localhost")

dbWriteTable( db, value = "tmp.csv", name = "test1", append = TRUE, row.names = FALSE, sep = ",", quote='\"', eol="\r\n")

答案 1 :(得分:0)

最后,看来这是连接编码设置的问题。默认情况下,我的连接设置为utf-8,但我的本地编码设置为latin1。因此,我的最终解决方案是:

con <- dbConnect(MySQL(), user=user, password=password,dbname=dbname, host=host, port=port)
# With the next line I try to get the right encoding (it works for Spanish keyboards)
encoding <- if(grepl(pattern = 'utf8|utf-8',x = Sys.getlocale(),ignore.case = T)) 'utf8' else 'latin1'
dbGetQuery(con,paste("SET names",encoding))
dbGetQuery(con,paste0("SET SESSION character_set_server=",encoding))
dbGetQuery(con,paste0("SET SESSION character_set_database=",encoding))
dbWriteTable( con, value = dfr, name = table, append = TRUE, row.names = FALSE )
dbDisconnect(con)

答案 2 :(得分:0)

我遇到了一个大约60列和150万行的数据表的问题;有许多计算值以及已对帐和更正的日期和时间,因此我不想重新格式化不需要重新格式化的任何内容。由于utf-8问题仅出现在字符字段中,因此我使用了一种kludgy-but-quick方法:

1)将字段列表从dbWriteTable语句复制到文字处理器或文本编辑器中

2)在副本上,仅保留描述为VARCHAR和TEXT的字段

3)将这些字段简化为字段名称

4)使用paste0编写语句的字符向量,以确保所有字段均为字符字段:

dt $ x <-as.character(dt $ x)

5)然后再次使用paste0编写将编码设置为UTF-8的语句的字符向量

Encoding(dt $ x)<-“ UTF-8”

在编码组之前运行as.character组。

这绝对是一个难题,还有更优雅的方法,但是如果您只需要不时这样做(就像我一样),则它具有三个优点: 1)它仅更改需要更改的内容(与我的项目一样,重要的是在数据表中已经存在大量您不希望重新格式化的工作), 2)在中间阶段不需要很多空间和读写操作,并且 3)写入速度快,并且至少可以在我正在使用的数据表大小下以可接受的速度运行。

不太优雅,但是它会很快带您解决这个特殊的问题。

答案 3 :(得分:0)

dbConnect() 函数有一个参数叫 encoding,可以帮助你轻松设置连接编码方式。

dbConnect(MySQL(), user=user, password=password,dbname=dbname, host=host, port=port, encoding="latin1")

这允许我将“ñ”字符插入到我的表格中,并将数据插入到名称中带有“ñ”的列中。例如,我可以将数据插入到名为“año”的列中。