运行rails测试套件时,MySql中出现“非法混合排序”错误

我最近拂去了我的一个旧的Ruby on Rails项目。 在过去,我从来没有遇到任何问题通过所有测试,但现在有一个测试,给我以下错误:

ActiveRecord :: StatementInvalid:Mysql :: Error:#HY000非法混合排序(latin1_swedish_ci,IMPLICIT)和(utf8_general_ci,COERCIBLE)操作’=’:SELECT * FROM cards WHERE(cards.l1_description =’是’AND cards.l2_word = ”)

所以我去我的测试数据库并询问:

mysql> use flashcard_test Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> show full columns from cards; +----------------+--------------+-------------------+------+-----+---------+----------------+---------------------------------+---------+ | Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment | +----------------+--------------+-------------------+------+-----+---------+----------------+---------------------------------+---------+ | id | int(11) | NULL | NO | PRI | NULL | auto_increment | select,insert,update,references | | | l2_word | varchar(255) | latin1_swedish_ci | YES | | NULL | | select,insert,update,references | | | l1_description | text | latin1_swedish_ci | YES | | NULL | | select,insert,update,references | | | l1_id | int(11) | NULL | YES | | NULL | | select,insert,update,references | | | l2_id | int(11) | NULL | YES | | NULL | | select,insert,update,references | | +----------------+--------------+-------------------+------+-----+---------+----------------+---------------------------------+---------+ 5 rows in set (0.01 sec) 

正如你所看到的,整理是latin1_swedish_ci,大概是如果它是“utf8_general_ci”,我的问题就会得到解决。 值得庆幸的是,我的开发数据库已经没问题,所以我去了

 rake db:test:clone_structure 

并返回到MySql并再次检查测试数据库

 mysql> show full columns from cards; +----------------+--------------+-----------------+------+-----+---------+----------------+---------------------------------+---------+ | Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment | +----------------+--------------+-----------------+------+-----+---------+----------------+---------------------------------+---------+ | id | int(11) | NULL | NO | PRI | NULL | auto_increment | select,insert,update,references | | | l2_word | varchar(255) | utf8_general_ci | YES | | NULL | | select,insert,update,references | | | l1_description | text | utf8_general_ci | YES | | NULL | | select,insert,update,references | | | l1_id | int(11) | NULL | YES | | NULL | | select,insert,update,references | | | l2_id | int(11) | NULL | YES | | NULL | | select,insert,update,references | | +----------------+--------------+-----------------+------+-----+---------+----------------+---------------------------------+---------+ 5 rows in set (0.00 sec) 

啊,所以现在一切都很好看,所以我再一次

 rake test 

但是我再次遇到同样的问题,当我检查我的测试数据库时,我发现校对列已经重置为latin1_swedish_ci。

我不太了解rake测试是如何工作的,但我的工作假设是它使用schema.rb重新创建数据库。 现在,在我的一次迁移中,我得到了

  class CreateCards  "DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci" do |t| t.column :english_word, :string t.column :chinese_description, :text end end def self.down drop_table :cards end end 

这显然已经解决了那里的整理问题。 (我有另一个迁移,分别将english_word和chinese_description重命名为l2_word和l1_description。)但是这些信息还没有成为schema.rb。 不知何故,显然,MySql决定假设我想要latin1_swedish_ci。

总而言之,我认为我需要做的是以某种方式编辑某些东西,以便我将使用utf8_general_ci整理,然后我的问题就会消失(对吧?)。 但我无法弄清楚如何在“rake test”执行此操作时生成运行的代码。 有人可以帮忙吗?

对于它的价值,测试和开发数据库都被创建为

 create database flashcard_test default character set utf8 default collate utf8_general_ci; 

 create database flashcard_development default character set utf8 default collate utf8_general_ci; 

而我的database.yml有

 development: adapter: mysql database: flashcard_development username: root password: encoding: utf8 test: adapter: mysql database: flashcard_test username: root password: encoding: utf8 collation: utf8_general_ci 

http://nhw.pl/wp/2008/09/16/mysql-collat​​e-setting-in-rails-application似乎暗示这个问题与RoR和MySql之间的连接有关,但我还没有对那里的建议有任何好运。

将collat​​ion:utf8_general_ci添加到您已经完成的database.yml文件应该可以解决问题。 尝试使用“rake RAILS_ENV = test db:migrate:reset db:fixtures load”重新创建测试数据库 – 警告这将清除除了灯具之外的所有数据。

这对我有用。 要validation是否可以执行以下操作来查看数据库,表和列的排序规则:

 -- Database Collations: SELECT schema_name,default_character_set_name,default_collation_name FROM information_schema.SCHEMATA WHERE schema_name not IN ('mysql'); -- Table Collations: SELECT T.table_schema, T.table_name, T.TABLE_COLLATION, CCSA.CHARACTER_SET_NAME FROM information_schema.`TABLES` T, information_schema.`COLLATION_CHARACTER_SET_APPLICABILITY` CCSA WHERE CCSA.collation_name = T.table_collation AND T.table_schema not IN ('mysql'); -- Column Collations: SELECT table_schema, table_name, column_name, collation_name, character_set_name FROM information_schema.`COLUMNS` C WHERE C.table_schema not IN ('mysql') ORDER BY 1,2,4; 

现在,测试数据库中的所有内容都应该具有database.yml中指定的排序规则。