2010-10-10 6 views
6

Ich habe vor kurzem ein altes Ruby on Rails-Projekt von mir entstaubt. In der Vergangenheit habe ich nie irgendwelche Probleme bekommen alle Tests bestehen, aber jetzt gibt es einen Test, der mir die folgende Störung gibt:"Illegale Mischung von Sortierungen" Fehler von MySql beim Laufen Schienen Testsuite

ActiveRecord::StatementInvalid: Mysql::Error: #HY000Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation '=': SELECT * FROM cards WHERE (cards.l1_description = '是' AND cards.l2_word = '')

Also ich meinen Test db gehen und fragen:

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) 

Und wie Sie sehen können, ist die Sortierung latin1_swedish_ci und vermutlich, wenn es "utf8_general_ci" wäre, wären meine Probleme gelöst. Zum Glück ist meine Entwicklung Datenbank schon in Ordnung, so dass ich gehen und

rake db:test:clone_structure 

und zurück zu MySql und prüfen Sie erneut im Test db

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) 

Ah, jetzt ist alles gut aussieht, so noch einmal

I
rake test 

Aber ich habe das gleiche Problem noch einmal, und wenn ich meinen Test db überprüfen, finde ich, dass die Sortierspalte zurückgesetzt latin1_swedish_ci wurde.

Ich verstehe nicht sehr gut, wie Rake-Test funktioniert, aber meine Arbeitshypothese ist, dass es die DB mit schema.rb neu erstellt. Nun, in einer meiner Migrationen, habe ich

class CreateCards < ActiveRecord::Migration 
    def self.up 
    create_table :cards, :options => "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 

Und das hat offenbar das collate Problem dort aufgepasst. (Ich habe eine andere Migration, die englisch_word und chinese_description in l2_word bzw. l1_description umbenennt.) Aber diese Information hat es nicht in schema.rb geschafft. Und irgendwie hat MySql anscheinend entschieden, dass ich latin1_swedish_ci haben möchte.

Also, was ich denke ich muss irgendwie etwas bearbeiten, so dass ich die utf8_general_ci Sortierung verwenden werde, und dann werden meine Probleme verschwinden (richtig?). Aber ich kann nicht herausfinden, wie man den Code macht, der ausgeführt wird, wenn man "Rake-Test" macht. Kann jemand helfen?

Für das, was es wert ist, sowohl die Test- und Entwicklungsdatenbanken als

create database flashcard_test default character set utf8 default collate utf8_general_ci; 

und

create database flashcard_development default character set utf8 default collate utf8_general_ci; 

Und mein database.yml hat

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-collate-setting-in-rails-application scheint darauf hinzudeuten erstellt wurden dass dieses Problem etwas mit der Verbindung zwischen RoR und MySql zu tun hat, aber ich hatte kein Glück mit den Vorschlägen dort.

Antwort

5

Hinzufügen der Kollatierung: utf8_general_ci zu Ihrer Datenbank.yml-Datei, wie Sie getan haben, sollte den Trick tun. Versuchen Sie, die Testdatenbank mit "Rake RAILS_ENV = Test db: migrate: reset db: Fixtures Load" neu zu erstellen - Warnung, dies löscht alle Daten, die Sie dort hinter den Fixtures haben.

Das hat bei mir funktioniert.siehe die Sortierung auf der Datenbank zu überprüfen, Tabellen und Spalten können Sie führen die folgenden Schritte aus:

-- 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; 

Alles in Ihrer Testdatenbank nun die Sortierung in database.yml angegeben haben sollte.

Verwandte Themen