utf8数据在mysql中看起来很好,但在rails中被破坏了

2024-03-01

我正在为我的一位同事设置一个 Rails 环境,他使用的是 Mac(如果相关的话)。我已经从我们的实时 mysql 数据库中提取了数据,并使用该数据创建了一个本地开发数据库。如果我打开 mysql 控制台,并查看其名称字段中具有扩展字符集字符的记录的数据,那么它看起来很好。然而,在 Rails 控制台(以及 Rails 生成的网页)中,编码被破坏:例如,endash 被替换为“–”。

我所知道的唯一与此相关的 Rails 配置选项位于 config/database.yml 中。我目前有这套:

encoding: utf8
collation: utf8_general_ci

例如,这使得它在我的机器上运行良好。但就像我说的,它在我同事的机器上不起作用。有人有什么想法吗?

编辑1:在实时服务器上,我从其中复制数据,字符集信息如下所示:

mysql> show variables like 'char%';
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | latin1                     | 
| character_set_connection | latin1                     | 
| character_set_database   | latin1                     | 
| character_set_filesystem | binary                     | 
| character_set_results    | latin1                     | 
| character_set_server     | latin1                     | 
| character_set_system     | utf8                       | 
| character_sets_dir       | /usr/share/mysql/charsets/ | 
+--------------------------+----------------------------+

编辑2:为了回应@eggyal的评论,我做了几个mysqldump,这非常有启发性。这是第一个转储:

$ mysqldump -u root -h127.0.0.1  dbname lessons --where="id=79510"
-- MySQL dump 10.11
--
-- Host: 127.0.0.1    Database: e_learning_resource_v3
-- ------------------------------------------------------
-- Server version   5.0.32-Debian_7etch4-log

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `lessons`
--

DROP TABLE IF EXISTS `lessons`;
CREATE TABLE `lessons` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(255) default NULL,
  `description` text,
  `user_id` int(11) default NULL,
  `created_at` datetime default NULL,
  `privacy` int(11) default '1',
  `is_official` tinyint(1) default '0',
  `is_readonly` tinyint(1) default NULL,
  `comments_allowed` tinyint(1) default NULL,
  `hours` int(11) default NULL,
  `sessions` int(11) default NULL,
  `updated_at` datetime default NULL,
  `custom_menu_swf` varchar(255) default NULL,
  `pupil_liked_at` datetime default NULL,
  `user_liked_at` datetime default NULL,
  `pupil_favorite_count` int(11) default '0',
  `user_favorite_count` int(11) default '0',
  `teacher_notes` text,
  `pupil_notes` text,
  PRIMARY KEY  (`id`),
  KEY `user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Dumping data for table `lessons`
--
-- WHERE:  id=79510

LOCK TABLES `lessons` WRITE;
/*!40000 ALTER TABLE `lessons` DISABLE KEYS */;
INSERT INTO `lessons` VALUES (79510,'Jazz–Man',NULL,NULL,'2014-04-03 12:08:05',1,0,NULL,NULL,NULL,NULL,'2014-04-03 12:08:05',NULL,NULL,NULL,0,0,NULL,NULL);
/*!40000 ALTER TABLE `lessons` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2014-04-03 11:16:42

所以,这只是一个直接的 mysqldump,并且在“INSERT INTO Lessons”行中包含损坏的字符(Jazz-Man)。

我使用一些额外的选项再次执行此操作,数据在转储文件中看起来正常:

$ mysqldump -u root -h127.0.0.1  dbname lessons --extended-insert --single-transaction --default-character-set=latin1 --skip-set-charset --where="id=79510" 
-- MySQL dump 10.11
--
-- Host: 127.0.0.1    Database: e_learning_resource_v3
-- ------------------------------------------------------
-- Server version   5.0.32-Debian_7etch4-log
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;

--
-- Table structure for table `lessons`
--

DROP TABLE IF EXISTS `lessons`;
CREATE TABLE `lessons` (
  `id` int(11) NOT NULL auto_increment,
  `name` varchar(255) default NULL,
  `description` text,
  `user_id` int(11) default NULL,
  `created_at` datetime default NULL,
  `privacy` int(11) default '1',
  `is_official` tinyint(1) default '0',
  `is_readonly` tinyint(1) default NULL,
  `comments_allowed` tinyint(1) default NULL,
  `hours` int(11) default NULL,
  `sessions` int(11) default NULL,
  `updated_at` datetime default NULL,
  `custom_menu_swf` varchar(255) default NULL,
  `pupil_liked_at` datetime default NULL,
  `user_liked_at` datetime default NULL,
  `pupil_favorite_count` int(11) default '0',
  `user_favorite_count` int(11) default '0',
  `teacher_notes` text,
  `pupil_notes` text,
  PRIMARY KEY  (`id`),
  KEY `user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Dumping data for table `lessons`
--
-- WHERE:  id=79510

LOCK TABLES `lessons` WRITE;
/*!40000 ALTER TABLE `lessons` DISABLE KEYS */;
INSERT INTO `lessons` VALUES (79510,'Jazz–Man',NULL,NULL,'2014-04-03 12:08:05',1,0,NULL,NULL,NULL,NULL,'2014-04-03 12:08:05',NULL,NULL,NULL,0,0,NULL,NULL);
/*!40000 ALTER TABLE `lessons` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

-- Dump completed on 2014-04-03 11:18:20

所以,看起来额外的选项起到了作用:

--extended-insert --single-transaction --default-character-set=latin1 --skip-set-charset

当MySQL客户端与服务器交互时:

  1. 服务器仅接收字节串形式的任何文本;客户端之前会告诉它如何对此类文本进行编码。

  2. 如果服务器必须将该文本存储在表中,则必须将其转码为相关列的编码(如果不同)。

  3. 如果客户端随后想要检索此类文本,服务器必须将其转码为客户端期望的编码。

如果客户端在步骤 1 和 3 中使用的编码是same(通常是这种情况,特别是当两种情况下的客户端都是同一个应用程序时),如果客户端使用的编码与它所说的编码不同,那么通常会被忽视。例如,假设客户端告诉MySQL它将使用latin1,但实际上发送数据utf8:

  • 字符串'Jazz–Man'以 UTF-8 格式发送到服务器0x4a617a7ae280934d616e.

  • MySQL 在 Windows-1252 中解码这些字节,将它们理解为表示字符串'Jazz–Man'.

  • 存储在一个utf8列,MySQL 将字符串转码为其 UTF-8 编码0x4a617a7ac3a2e282ace2809c4d616e。这可以通过使用来验证SELECT HEX(name) FROM lessons WHERE id=79510.

  • 当客户端检索该值时,MySQL 认为它想要它latin1因此转码为 Windows-1252 编码0x4a617a7ae280934d616e.

  • 当客户端收到这些字节时,它将它们解码为 UTF-8,因此将字符串理解为'Jazz–Man'.

结论: 客户没有意识到有什么问题。仅当不同的客户端(不会将其 UTF-8 连接误述为latin1)尝试使用该表。在您的情况下,当 mysqldump 获得数据导出时发生这种情况;使用--default-character-set=latin1 --skip-set-charset选项有效地强制 mysqldump 以与应用程序相同的损坏方式运行,因此它最终得到正确编码的数据。

要解决您的问题,您必须:

  1. 配置您的应用程序,以便正确设置其 MySQL 连接字符集(例如 setencoding: utf8 in config/database.yml对于轨道);

  2. 重新编码数据库中的数据,例如UPDATE lessons SET name = BINARY CONVERT(name USING latin1)(请注意,必须对每个错误编码的文本列执行此操作)。

另请注意,您可能希望自动执行这两个操作,这可能需要一些思考。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

utf8数据在mysql中看起来很好,但在rails中被破坏了 的相关文章

  • 如何正确安装mysqlconnecter java?

    上网冲浪后 我意识到我应该在系统环境变量中设置类路径连接器 jar 文件的路径文件我这样做了 并在命令行中输入此命令我有这个 C Users User gt echo classpath D classpath mysql connecto
  • 从 MySQL 列创建 PHP 数组

    mysql fetch array会给我一个获取行的数组 从一列中所有行的值生成数组的最佳方法是什么 您可以循环遍历数组并创建一个新数组 如下所示 column array while row mysql fetch array info
  • PHP 从表行中检索数据并将其存储到变量

    我想这些问题已经说明了一切 我的查询结果会生成与条件匹配的行 我想从每个表列中获取每个数据并将其放入一个变量中 getinfo select user firstname user middlename user lastname from
  • 单表继承发现问题

    我有以下3个rails类 它们都存储在一张表中 使用rails的单表继承 class Template lt ActiveRecord Base class ThingTemplate lt Template class StockThin
  • .js.erb VS .js

    将 Rails 应用程序的 javascript 放入 js erb 文件而不只是将其放入 application js 文件有什么好处 我有一个企业创建按钮 因此我应该将代码放入 create js erb 文件中 还是使用以下方法将其放
  • ruby 调试和黄瓜

    我在 Cucumber 中遇到了失败的情况 我想使用 ruby debug 来调试我的 Rails 控制器 但是 如果我将 调试器 添加到我想要中断的位置 它就不会停止 我尝试将 ruby debug 和 ruby gems 的 requi
  • FIND_IN_SET 具有多个值[重复]

    这个问题在这里已经有答案了 我想从数据库字段搜索多个值 以下是我的查询 SELECT FROM tablename WHERE FIND IN SET 12 13 15 15 category id 我如何搜索它对我不起作用 FIND IN
  • 删除所有值比第二高值低 5 倍的记录

    我有一个表 价格 有两个字段 代码 字符 和价格 小数 我需要查找具有相同代码 价格比两个最高价格低 5 倍或更少的所有记录 例如 在这种情况下 我希望删除 id 1 id code price 1 1001 10 2 1001 101 3
  • 在不使用 PHP 的情况下将 MYSQL 中的表字段更新为其值加上常量

    我想表演一个UPDATE in MYSQL其中我获取一个字段值 添加一个常量并将新值保存在同一字段中 假设我们有一个名为OldValue在一个名为aTable 伪代码可能是 UPDATE aTable SET OldValue OldVal
  • 尽管我安装了 2.2.2,为什么我会收到错误“您的 Ruby 版本是 2.0.0,但您的 Gemfile 指定了 2.2.2”

    我正在使用 rbenv 但出现错误Your Ruby version is 2 0 0 but your Gemfile specified 2 2 2当我运行bundle install我的项目中的命令 奇怪的是 我实际上安装了 2 2
  • 通过日期选择器过滤查询后检索具有特定值的行数[重复]

    这个问题在这里已经有答案了 目前 我正在使用 CodeIgniter 来检索特定时间范围内的数据 所有这些条目都有一个状态 我想将具有相同状态的所有条目分组并将其显示在各自的标题中 目前 这是我的模型类 其中我有以下条目来返回特定日期范围内
  • 如何更改Mysql的连接排序规则

    如何更改 mysql 数据库的连接排序规则 我在 ubuntu 14 中使用 Mysql workbench 5 5 和 mysql 5 5 当我执行存储过程时 出现错误 错误代码 1267 操作 的排序规则 utf8 general ci
  • 重新归档 simple_form 未定义方法 Attachment_field

    I am trying to hook up refile to my view and I am getting the following error 这是我的模型 class Job lt ActiveRecord Base acts
  • 使用 shoulda 重构 Rails 模型上的 rspec 测试

    了解后应该匹配器 https github com thoughtbot shoulda matchers通过回答关于属性可访问性测试的另一个 StackOverflow 问题 https stackoverflow com a 11849
  • RSpec 抛出分段错误

    有时我的测试套件会无缘无故地抛出分段错误 这是输出 Users Test rvm gems ruby 1 9 3 p392 gems activerecord 3 2 9 lib active record relation query m
  • 在 Rails 上制作 ruby​​ 占用更少的内存

    我正在尝试运行 Ruby on Rails 项目 redmine http www redmine org 在 VPS 上 它可以工作 但需要相当多的内存 与 VPS 的其余部分相比 rails 应用程序的使用量非常少 我的服务器上也运行着
  • 如何将mysql数据库移动到另一个安装点

    我有一个 MySQL 数据库 它变得越来越大 我想将整个数据库移动到另一个安装点 在那里我有足够的存储空间 我希望传输当前数据 并将新数据保存到新位置 软件堆栈 在 FreeBSD 6 上运行的 MySQL 5 当然其他答案也是有效的 但如
  • MYSQL数据库删除行后需要进行后期优化

    我有一个当前为 10GB 的日志表 它有很多过去两年的数据 我真的觉得目前我不需要那么多 我是否错误地认为在表中保存多年的数据不好 表越小越好 我的桌子都有 MYISAM 引擎 我想删除 2014 年和 2015 年的所有数据 很快我就会删
  • PHP strtotime返回Mysql UNIX_TIMESTAMP的不同值

    我在 stackoverflow 上搜索过帖子 发现了一些类似的帖子 但我认为这是一篇不同的帖子 我的 PHP 和 Mysql 服务器的时区全部设置为 UTC 在表中我使用时间戳字段 值为 2010 11 08 02 54 15 我使用这样
  • 为什么 .each 在我的 Rails 视图中完成后会重复数组? [复制]

    这个问题在这里已经有答案了 在我的 Rails 视图页面中 我有以下循环 它应该循环遍历我的 tag list 数组并打印每个标签 由于某种原因 它在打印每个单独的标签后会重复该数组 例如 这个数组有两个元素 ruby python 每个方

随机推荐

  • React Hooks 中的 Push 方法(useState)?

    如何将元素推送到 useState 数组 React hook 中 这是反应状态下的旧方法吗 或者新的东西 E g setState 推送示例 https stackoverflow com questions 41052598 react
  • 默认情况下,Spring Boot 期望视图存储在哪里?

    我正在尝试使用 Spring Boot 重写我的配置繁重的普通 Spring MVC 项目 我使用 Spring Boot Initiaizer 在 IntelliJ 中启动了一个全新的 Spring Boot 项目 并且我将采用基于 Ja
  • pandas groupby 一次用于多个数据帧/文件

    我有多个巨大的 tsv 文件 我正在尝试使用 pandas 处理它们 我想按 col3 和 col5 分组 我试过这个 import pandas as pd df pd read csv filename txt sep t g2 df
  • Web API 将对象传递给 Get 方法

    有没有办法在 Web API 的 Get 方法中将对象作为参数传递 我有以下案例 在我的 Web API 项目中 Get 方法如下所示 public IEnumerable
  • 可以在事件处理函数中删除 POSIX 计时器吗?

    问题 如果我打电话create timer与SIGEV THREAD常量存储在sigev notify我的领域sigevent结构 那么当计时器事件发生时 我的sigev notify function回调将被调用 调用是否有任何隐藏的含义
  • audioop.rms() - 为什么它与正常的 RMS 不同?

    我正在编写一个 python 函数来返回 wav 文件的响度 RMS 似乎是最好的衡量标准 用python检测并记录声音 https stackoverflow com questions 2668442 detect and record
  • 按顺序显示多个Toast的问题

    对不起 我的英语不好 我想按顺序显示两个吐司 换句话说 当第一个吐司持续时间超过第二个吐司时出现 这是我的代码 Toast makeText this Toast1 Toast LENGTH SHORT show Toast makeTex
  • 在 SwiftUI 中连续重复操作

    如何使文本字段等元素连续放大然后缩小 我有这个 struct ContentView View State var size Double 0 5 var body some View ZStack Text Hello padding s
  • 为什么 JLabel 当第一个字符时不显示“/”?

    我有一个摆动面板 里面有一个 JLabel JLabel 看起来像这样 new JLabel Foo br Bar br Foo br Bar 但它在 UI 中显示如下 Bar Foo Bar 由于某种原因 第一行就消失了 如果我去掉斜杠或
  • UDP 数据包在交付时是否保证是完整的、具有实际意义的?

    众所周知 UDP 用户数据报协议 并不安全 因为用它发送的数据包的顺序可能不按顺序传送 甚至根本不按顺序传送 但是 如果发送了 UDP 数据包 该数据包中的信息在实际意义上 99 99 及以上 是否保证正确 在实际意义上 99 99 及以上
  • keytab 到底是如何工作的?

    我对使用 keytab 进行身份验证有一些疑问 希望这里的好心人可以启发我 假设我有一个用户 A 他将使用在端口 1010 上运行的服务 首先 用户 A 将登录到 Active Directory 来验证自己的身份 登录后 userA 将尝
  • 求两个向量之间的差异

    我有两个向量 a lt 1 100 b lt sample 1 100 80 我想显示 a 中未包含在 b 中的那些元素 我努力了subset a a b and a a b 但这些都不起作用 我究竟做错了什么 由于 R 中的矢量化 使用
  • Ubuntu 10服务器上配置Tomcat6 + apache2.2的问题

    我正在尝试在 Ubuntu 服务器 10 上使用 apache 2 2 配置 Tomcat6 我遵循了很多教程 但我无法使其工作 请问有人可以帮助我吗 这是一些信息 mod jk so 位于 apache 模块文件夹中 我的工人属性 wor
  • IGraphBuilder.RenderFile 中无法播放 MP3 文件并出现 COM 异常

    我是导演节目开发的新手 我正在学习有关直接表演的知识 我正在尝试编写一种播放一些音频文件的方法 它适用于许多 mp3 文件 但对于我的某些 mp3 文件 接口 IGraphBuilder 的方法 RenderFile 抛出以下异常 发生 C
  • 检测滑动手势方向

    这是我尝试模拟滑动手势的代码 因此当我构建移动设备时 我知道它会起作用 没有记录任何内容 我很困惑为什么它似乎不起作用 我希望它在我滑动的控制台中打印出来RTL 从右到左 或LTR 左到右 我不明白我做错了什么 void Update if
  • 如何在 Sails.js 中压缩 JavaScript 和 CSS 资源?

    我正在尝试在 Sails js Node 应用程序中为我的资产启用 gzip 压缩 在生产环境中启动应用程序时 所有资产assets linker js and assets linker styles已成功连接 缩小 丑化 如 Grunt
  • 如何从 CLI 构建 DocC 文档

    所以我已经浏览网页有一段时间了 似乎找不到有关如何构建的答案本机 DocC Xcode 文档 使用 CLI 命令 这俩xcodebuild据我所知 commands 和 Fastlane 不提供构建文档的命令 应该构建文档CI CD Git
  • IllegalArgumentException:ID 未引用此 Activity 内的视图

    我一直在尝试为我的应用程序制作一个主页 其中包含一些现代仪表板和导航抽屉 在我的代码中发现错误 E AndroidRuntime FATAL EXCEPTION main Process com example thinkerlab PID
  • 在 MacOS 上使用 cx_freeze 打包 tkinter GUI 会导致黑色 GUI

    我正在构建一个tkinter一位朋友在运行 macOS Catalina 10 15 2 的 Mac 上使用 Python 3 8 3 的 GUI 并尝试使用冻结它cx freeze 6 1 当我在本地环境中运行 python 应用程序时
  • utf8数据在mysql中看起来很好,但在rails中被破坏了

    我正在为我的一位同事设置一个 Rails 环境 他使用的是 Mac 如果相关的话 我已经从我们的实时 mysql 数据库中提取了数据 并使用该数据创建了一个本地开发数据库 如果我打开 mysql 控制台 并查看其名称字段中具有扩展字符集字符