【问题标题】:saving utf8mb4 strings to mysql将utf8mb4字符串保存到mysql
【发布时间】:2013-03-27 08:08:03
【问题描述】:

我有一个包含 utf8mb4 字符的 JSON 字符串。我首先解析 JSON,然后将结果编码回 JSON。之后,我将生成的 JSON 保存到 mysql 数据库。 (这是一个简化的执行流程,我首先解析 JSON 然后将其编码回来是有实际原因的。

问题是数据库以我放在那里的 JSON 字符串的前缀结尾,并且在第一个 utf8mb4 字符处被截断。

这是我的代码:

require 'json'
require 'mysql2'

TABLENAME = 'my_table'

settings = {
  :database => "my_database",
  :host => "localhost",
  :password => "my_password",
  :username => "my_username"
}

@database = Mysql2::Client.new settings
@json = %q({"test":"begin \ud83d\ude04\ud83d\udc4d\ud83d\udc4f\ud83d\udd14 end"})

begin
  obj = JSON.parse @json
rescue JSON::ParserError => e
  @json.force_encoding 'utf-8'
  encoded = @json.valid_encoding? ? @json : @json.encode!('utf-8', invalid: :replace, undef: :replace)
  obj = JSON.parse encoded
end

q = "create table if not exists `#{TABLENAME}` (json text not null) engine=InnoDB default charset=utf8"
@database.query q

text = @database.escape JSON.generate obj
q = "insert ignore into `#{TABLENAME}` (json) values('#{text}')"
@database.query q

q = "select * from `#{TABLENAME}`"
rs = @database.query q

rs.each {|r|
  p r
}

输出是:

{"json"=>"{\"test\":\"begin "}

我不知道为什么会发生这种情况,我将不胜感激!

【问题讨论】:

  • 当您使用更简单的非 ASCII 内容 éµ 而不是表情符号时,它是否有效?
  • @muistooshort 感谢您的评论,我没有意识到这与它们是 mb4 字符有关。如果我将 \u0428 (Cyrillic Ш) 插入到字符串中(在截断字符之前),那么它会成功保存。
  • 我不得不玩弄\u 的东西才能发现它。 JavaScript 似乎对它们很满意,而 Ruby 1.9.2 则不然。如果你不通过数据库发送任何东西会发生什么?或者如果你使用二进制列类型而不是字符串类型?
  • 如果我使用blob 作为列类型,它有点工作,但它显示为{"json"=>"{\"test\":\"begin \xD0\xA8 \xF0\x9F\x98\x84\xF0\x9F\x91\x8D\xF0\x9F\x91\x8F\xF0\x9F\x94\x94 end\"}"}

标签: ruby unicode mysql2 emoji


【解决方案1】:

感谢@muistooshort 帮助我找到解决此问题的方法:

...
settings = {
  ...
  :encoding => 'utf8mb4'
}
...
q = "create table ... default charset=utf8mb4"
...

这当然只适用于支持 utf8mb4 的引擎。

【讨论】:

    猜你喜欢
    • 2015-02-07
    • 2020-02-17
    • 2014-07-02
    • 2015-10-20
    • 1970-01-01
    • 2016-05-09
    • 2012-07-04
    • 2015-04-14
    • 2012-09-28
    相关资源
    最近更新 更多