Mysql Ruby 1.9.3上的Rails 2.3编码错误
我正在将一个旧的Rails 2.3应用程序升级到更现代的版本,并且遇到了编码问题。我已经阅读了关于这个问题的所有现有答案,但我仍然遇到问题 轨道版本:2.3.17 Ruby版本:1.9.3p385 我的MySQL表是默认字符集:Mysql Ruby 1.9.3上的Rails 2.3编码错误,mysql,ruby-on-rails,ruby,unicode,Mysql,Ruby On Rails,Ruby,Unicode,我正在将一个旧的Rails 2.3应用程序升级到更现代的版本,并且遇到了编码问题。我已经阅读了关于这个问题的所有现有答案,但我仍然遇到问题 轨道版本:2.3.17 Ruby版本:1.9.3p385 我的MySQL表是默认字符集:utf8,排序规则:utf8\u general\u ci。在1.9之前,我使用的是原始的mysqlgem,没有任何意外。升级到1.9后,当它检索到任何包含utf8字符的内容时,它将遇到以下问题: ActionView::TemplateError (incompatib
utf8
,排序规则:utf8\u general\u ci
。在1.9之前,我使用的是原始的mysql
gem,没有任何意外。升级到1.9后,当它检索到任何包含utf8字符的内容时,它将遇到以下问题:
ActionView::TemplateError (incompatible character encodings: ASCII-8BIT and UTF-8)
我切换到了mysql2
gem,因为它具有出色的处理能力,我再也看不到异常,但显然编码不正确。例如,数据库中出现的字符串repousse
由Rails呈现为Repoussé
,“Boat”
显示为船€
,等等
还有一些细节:
- 当我使用
gem作为驱动程序时,我看到了相同的结果李>rubymysql
- 我已经在我的
数据库.yml中的每个条目中添加了
行编码:utf8
环境.rb
:
Encoding.default_external = Encoding::UTF_8
Encoding.default_internal = Encoding::UTF_8
我突然想到,我可能有一些不匹配的地方,latin1被旧版本的应用程序写入数据库的utf8字段或其他内容,但在mysql
命令行客户端中查看时,所有字符都正确显示
提前感谢您的建议,非常感谢
更新:我现在认为问题在于,我的utf8数据在离开db的过程中被强制转换成拉丁文1,我只是不知道在哪里
mysql> SELECT CONVERT(CONVERT(name USING BINARY) USING latin1) AS latin1, CONVERT(CONVERT(name USING BINARY) USING utf8) AS utf8 FROM items WHERE id=myid;
+-------------+----------+
| latin1 | utf8 |
+-------------+----------+
| Repoussé | Repoussé |
+-------------+----------+
我在database.yml中将我的
encoding
设置为utf8
,还有其他想法吗?你说在命令行客户端看起来一切正常,但也许你的终端的字符编码没有设置为显示utf8?要签入OSX终端,请单击终端>首选项>设置>高级>字符编码。另外,使用诸如MySQL查询浏览器之类的图形工具进行检查。我终于找到了问题所在。当我的数据库使用utf8
编码时,使用原始mysql
gem的应用程序将latin1
文本注入utf8
表中
让我不快的是mysql comand line客户端的输出看起来是正确的。验证终端、数据库字段和MySQL客户端是否都在utf8
中运行,这一点很重要
默认情况下,MySQL的客户端在latin1
中运行。您可以通过发出以下查询来发现它在运行什么:
show variables like 'char%';
如果正确设置了utf8
,您应该看到:
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
如果这些看起来不正确,请确保在my.cnf
配置文件的[client]
部分设置了以下内容:
default-character-set = utf8
将以下内容添加到[mysqld]
部分:
# use utf8 by default
character-set-server=utf8
collation-server=utf8_general_ci
确保在重新启动客户端之前重新启动mysql守护程序,然后进行验证
注意:这不会更改现有数据库的字符集或排序规则,只会确保创建的任何新数据库将默认为utf8
,并且客户端将显示在utf8
中
在我这样做之后,我在mysql客户机中看到的字符与我从mysql2
gem获得的字符相匹配。我还可以通过在我的数据库.conf
中临时切换到“编码:拉丁语1
”来验证此内容是否为latin1
查找问题的一个非常方便的查询是使用char length查找具有多字节字符的行:
SELECT id, name FROM items WHERE LENGTH(name) != CHAR_LENGTH(name);
有很多脚本可以将latin1
内容转换为utf8
,但对我来说最有效的方法是将所有数据库转储为latin1,并将内容以utf8
的形式重新填充:
mysqldump -u root -p --opt --default-character-set=latin1 --skip-set-charset DBNAME > DBNAME.sql
mysql -u root -p --default-character-set=utf8 DBNAME < DBNAME.sql
mysqldump-u root-p--opt--default character set=latin1--skip set charset DBNAME>DBNAME.sql
mysql-u root-p——默认字符集=utf8 DBNAME
我首先备份了我的主数据库,然后将其转储到测试数据库中,并疯狂地进行了验证,然后转到正确的数据库
我的理解是,MySQL的翻译可能会留下一些更复杂的字符,但由于我的大多数多字节字符是相当常见的东西(重音符号、引号等),这对我来说非常有用
事实证明,一些资源在解决所有这些问题方面是非常宝贵的:
utf-8
?好主意,是的:
要更准确地定位问题源,我建议您使用记录器。调试模板、模型中的数据。我想,这不是一个破坏数据的mysql驱动程序。它肯定发生在视图层之前。如果我启动控制台并。查找受影响的模型,我可以在模型字段中看到编码问题。感谢您的建议!我的终端编码设置为UTF8。