Ruby 请教 ruby 怎么往 MySQL 里插中文

areosome · March 03, 2012 · Last by sleepless replied at June 02, 2016 · 6693 hits

我是菜鸟,大家不要笑我。。。

用 ruby 写了一个小爬虫,想把爬下来的数据存到 MySQL 里,没有用 dbi 或者 sequel,中文内容 insert 后会报错 1064,incompatible character encodings: UTF-8 and ASCII-8BIT (Encoding::CompatibilityError)

我试过用 force_encoding 转为 utf-8,可没什么用,还是同样的错误

在网上找了半天也没有什么好用的办法,希望大家指点一下啊

你的.rb 文件是不是没有 # encoding: utf-8

#1 楼 @azhao 不是这个原因吧,起码如果是缺少 # encoding: utf-8 绝对不是这个报错。也应该不是数据库的原因。因为数据库即使是 GBK 也应该可以存进去的。可能是不是网页的字符集非 UTF-8。只是猜想

如果不是代码中出现中文,恐怕是数据库的设置问题。 在 mysql 命令行中用 show variables like 'char%';看看是否有支持中文的字符集吧,比如 utf-8\gbk 什么的。

这个问题我时常会遇到,但是目前为止依然没找到根源(引出这个错误的原因有很多种) 结果就是反复查代码,不知不觉就解决了。 以前还发现某个 Cache 里面的数据导致出这个编码错误...

这个错误是 ruby 的 String 编码不合,应该跟 mysql 无关。

像是从 CSV 读资料进来时,若没有指定编码为 UTF-8,那读进来的 String 会是 ASCII-8BIT。

#5 楼 @chitsaou 嗯,我也这么认为的,看看爬的网页吧。

#5 楼 @chitsaou 嗯,我也是用 mysql+CSV 存取爬到的数据的时候会报错,所以后来就不用 csv,直接 open

String 编码,数据库连接编码,数据库编码,数据库表单编码……

有编码的地方很多,一个个排除

具体情况不清楚,不过提醒一下,有人会误用 force_encoding,而这个 api 是不改变原始的字节数组的

$ irb
1.9.2p290 :001 > "中".each_byte{|x| p x}
228
184
173
 => "中" 
1.9.2p290 :002 > "中".force_encoding('gbk').each_byte{|x| p x}
228
184
173
 => "\x{E4B8}\xAD" 

#6 楼 @soloara 我是解析 JSON 得到的数据,不过我自己随便写一个中文的字符串,force_encoding 为 utf-8 仍然是报这个错

加个 # encoding: utf-8 试试?

#11 楼 @zhaoguobin 加了的,不是这个原因

#4 楼 @huacnlee 昨晚还遇到了由于 cache 引起的这个问题,本地 dev 和 production 都好的,到服务器上 dev 好的,production 就是报错,最后发现是 memcached 的缓存问题。

这个问题我通常会在页面 render 的时候遇到,我一般这么查:

  • mysql 中通过 show variables like 'char%'; 确保是 utf8 的
  • 确保 ruby 文件加上了 # encoding: utf-8
  • 确保 Encoding.default_external,Encoding.default_internal 都是 Encoding::UTF_8
  • 如果有缓存,尝试清除缓存看看是否能解决

#13 楼 @kenshin54 谢谢,很有价值的建议

请问这个问题解决了吗?我现在也碰到这个问题,我是调用其它的网站的服务,返回的中文,我用 force_encoding 依然报上面的错误。

表示使用通杀方法 set names utf8 一直插入显示各种无问题

require 'mysql2'
c = Mysql2::Client.new(username:'scott',password:'tiger',database:'draw_something')
c.query('set names utf8')
c.query("insert into fuckphp set(name, action) values('php', 'fuck')")

@areosome 这个也有可能和你使用的 gem 包以及 ruby 版本有关系,你有用什么 html 解析插件么,最好把你的步骤列出来方便排查

@cdredfox String#force_encoding在ruby1.9.3下面只是更改字符串的编码标识,而不会更改字符自身的编码.Encoding#default_external,Encoding#default_internal的设置会对读进来的字符串编码产生影响~

c.query('set names gbk') 解决了我的乱码问题。mysql 数据库表是 gbk 的。但是仍然有一些乱码中文,insert 出错。

You need to Sign in before reply, if you don't have an account, please Sign up first.