我有一个在生产模式下运行的rails应用程序,但是当用户试图保存记录时,突然出现了这个错误。
Mysql2::Error: Incorrect string value
更多细节(来自生产日志):
Parameters: {"utf8"=>"â<9c><93>" ...
Mysql2::Error: Incorrect string value: '\xC5\x99\xC3\xA1k
Mysql2::Error: Incorrect string value: '\xC5\x99\xC3\xA1k
现在我看到了一些需要删除数据库并重新创建数据库的解决方案,但我不能这样做。
现在mysql显示了这个:
mysql> show variables like 'char%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.04 sec)
有什么问题,如何更改,以便我对任何字符都没有任何问题?
另外:这个问题可以用javascript解决吗?在发送之前转换它?
由于
答案 0 :(得分:72)
问题是由mysql服务器端的charset引起的。您可以手动配置:
ALTER TABLE your_database_name.your_table CONVERT TO CHARACTER SET utf8
或删除表并重新创建它:
rake db:drop
rake db:create
rake db:migrate
的引用:
https://stackoverflow.com/a/18498210/2034097
https://stackoverflow.com/a/16934647/2034097
<强>更新强>
第一个命令只影响指定的表,如果要更改数据库中的所有表,可以这样做
ALTER DATABASE databasename CHARACTER SET utf8 COLLATE utf8_general_ci;
参考:
答案 1 :(得分:38)
我设法按照blog post来存储表情符号(占用4个字节):
Rails 4,MySQL和Emoji(
Mysql2::Error: Incorrect string value error.
)您可能认为您可以安全地插入大多数utf8数据 当您指定charset为
utf-8
时,为mysql。可悲的是, 但是,你错了。问题是utf8字符集 存储在VARCHAR列中时占用3 bytes。表情符号字符 另一方面,占用 4个字节。解决方案分为两部分:
更改表格和字段的编码:
ALTER TABLE `[table]` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin, MODIFY [column] VARCHAR(250) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin
告诉
mysql2
适配器:development: adapter: mysql2 database: db username: password: encoding: utf8mb4 collation: utf8mb4_unicode_ci
希望这有助于某人!
然后我不得不重启我的应用程序并且它有效。 请注意,有些表情符号可以在没有此修复的情况下工作,而有些则不会:
答案 2 :(得分:23)
您可以使用此类迁移将表格转换为utf8:
class ConvertTablesToUtf8 < ActiveRecord::Migration
def change_encoding(encoding,collation)
connection = ActiveRecord::Base.connection
tables = connection.tables
dbname =connection.current_database
execute <<-SQL
ALTER DATABASE #{dbname} CHARACTER SET #{encoding} COLLATE #{collation};
SQL
tables.each do |tablename|
execute <<-SQL
ALTER TABLE #{dbname}.#{tablename} CONVERT TO CHARACTER SET #{encoding} COLLATE #{collation};
SQL
end
end
def change
reversible do |dir|
dir.up do
change_encoding('utf8','utf8_general_ci')
end
dir.down do
change_encoding('latin1','latin1_swedish_ci')
end
end
end
end
答案 3 :(得分:2)
如果你想要商店表情符号,你需要:
1)创建迁移(感谢@mfazekas)
class ConvertTablesToUtf8 < ActiveRecord::Migration
def change_encoding(encoding,collation)
connection = ActiveRecord::Base.connection
tables = connection.tables
dbname =connection.current_database
execute <<-SQL
ALTER DATABASE #{dbname} CHARACTER SET #{encoding} COLLATE #{collation};
SQL
tables.each do |tablename|
execute <<-SQL
ALTER TABLE #{dbname}.#{tablename} CONVERT TO CHARACTER SET #{encoding} COLLATE #{collation};
SQL
end
end
def change
reversible do |dir|
dir.up do
change_encoding('utf8mb4','utf8mb4_bin')
end
dir.down do
change_encoding('latin1','latin1_swedish_ci')
end
end
end
end
2)将rails charset更改为utf8mb4(感谢@ selvamani-p)
production:
encoding: utf8mb4
参考文献:
答案 4 :(得分:1)
需要为已创建的数据库更改CHARACTER SET
和COLLATE
:
ALTER DATABASE databasename CHARACTER SET utf8 COLLATE utf8_unicode_ci;
或者有必要使用预设参数创建数据库:
CREATE DATABASE databasename CHARACTER SET utf8 COLLATE utf8_general_ci;
答案 5 :(得分:0)
从数据库获取数据时,这似乎是一个编码问题。尝试将以下内容添加到database.yml文件
encoding: utf8
希望这能解决您的问题
答案 6 :(得分:0)
此外,如果您不想对数据库结构进行更改,可以选择序列化相关字段。
class MyModel < ActiveRecord::Base
serialize :content
attr_accessible :content, :title
end
答案 7 :(得分:0)
刚刚遇到这个问题,并感谢@mfazekas的回答。我在迁移中进行了两项更改:一种用于适应从connection.current_database中删除(至少在Rails 5中),以及如果不使用MySQL则可以跳过SQL语句的能力(我仍在开发中使用SQLite,但需要运行迁移)。
class ConvertTablesToUtf8 < ActiveRecord::Migration[5.2]
def change_encoding(encoding,collation)
# Allow for different adapter in different environment
return unless ActiveRecord::Base.connection_config[:adapter] == "mysql"
tables = connection.tables
dbname = ActiveRecord::Base.connection_config[:database]
execute <<-SQL
ALTER DATABASE #{dbname} CHARACTER SET #{encoding} COLLATE #{collation};
SQL
tables.each do |tablename|
execute <<-SQL
ALTER TABLE #{dbname}.#{tablename} CONVERT TO CHARACTER SET #{encoding} COLLATE #{collation};
SQL
end
end
def change
reversible do |dir|
dir.up do
change_encoding('utf8','utf8_general_ci')
end
dir.down do
change_encoding('latin1','latin1_swedish_ci')
end
end
end
end