在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");
我之前已经尝试过写表的事情:
为所有表格编码(x)&lt; - “UTF-8”。
iconv(x,“UTF-8”,“UTF-8”)。
发送预查询:dbSendQuery(db,“SET NAMES UTF8;”)
将MySQL表校对更改为:“utf-8-general,latin-1,latin-1-spanish ...”
*尝试过“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 :(
答案 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”的列中。