2010-10-10 16 views
6

मैंने हाल ही में रेल की परियोजना पर पुरानी रूबी को धूल दिया है। अतीत में, मैं किसी भी समस्याओं सभी परीक्षणों पारित करने के लिए हो रही थी कभी नहीं किया है, लेकिन अब वहाँ एक परीक्षण है कि मुझे निम्न त्रुटि देता है:"कॉलेशंस का अवैध मिश्रण" त्रुटि माईएसक्ल से त्रुटि

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 = '')

तो मैं अपने परीक्षण db के पास जाकर पूछते हैं:

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) 

और जैसा कि आप देख सकते हैं, collation latin1_swedish_ci है, और संभवतः अगर यह "utf8_general_ci" थी, तो मेरी समस्या हल हो जाएगी। शुक्र है, मेरे विकास डेटाबेस पहले से ही ठीक है, तो मैं जाने के लिए और

rake db:test:clone_structure 

और वापस MySql के लिए और परीक्षण 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) 

आह में फिर से जांच, इसलिए अब सब कुछ अच्छी लग रही है, तो एक बार फिर से मैं

rake test 

लेकिन मैं फिर से एक ही समस्या मिलता है, और जब मैं अपने परीक्षण डाटाबेस की जांच, मुझे लगता है कि मिलान स्तंभ latin1_swedish_ci को रीसेट किया गया है।

मुझे समझ में नहीं आता कि रेक परीक्षण कैसे काम करता है, लेकिन मेरी कामकाजी परिकल्पना यह है कि यह schema.rb का उपयोग कर डीबी को दोबारा शुरू करता है। अब, मेरे माइग्रेशन में से एक में, मुझे

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 

और यह स्पष्ट रूप से वहां कोलेट समस्या का ख्याल रखता है। (मुझे एक और माइग्रेशन मिला है जो क्रमशः l__word और l1_description में english_word और chinese_description का नाम बदलता है।) लेकिन इस जानकारी ने इसे schema.rb में नहीं बनाया है। और किसी भी तरह, जाहिर है, MySQL ने यह मानने का फैसला किया है कि मैं latin1_swedish_ci चाहता हूं।

तो, संक्षेप में, मुझे लगता है कि मुझे ऐसा करने की ज़रूरत है, किसी भी तरह से कुछ संपादित करें ताकि मैं utf8_general_ci संयोजन का उपयोग कर सकूं, और फिर मेरी समस्याएं दूर हो जाएंगी (दाएं?)। लेकिन जब आप "रेक टेस्ट" करते हैं तो कोड को चलाने के तरीके को समझ नहीं सकते हैं। क्या कोई मदद कर सकता है?

क्या इसके लायक है के लिए, दोनों परीक्षण और विकास डेटाबेस के रूप में

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-collate-setting-in-rails-application सुझाव देने के लिए लगता है है कि इस समस्या में RoR और MySQL के बीच कनेक्शन के साथ कुछ करना है, लेकिन मेरे पास सुझावों के साथ कोई भाग्य नहीं है।

उत्तर

5

collation जोड़ना: utf8_general_ci आपके डेटाबेस.इम.एल.एल. फाइल को आपके द्वारा किया गया है, यह चाल चलाना चाहिए। "रेक RAILS_ENV = test db: माइग्रेट: रीसेट डीबी: फिक्स्चर लोड" का उपयोग करके परीक्षण डेटाबेस को पुन: प्रयास करने का प्रयास करें - चेतावनी यह आपके पास मौजूद सभी डेटा को फिक्स्चर से परे साफ़ कर देगा।

यह मेरे लिए काम करता है।डेटाबेस, टेबल पर मिलान देखने सत्यापित करने के लिए, और कॉलम आप निम्नलिखित निष्पादित कर सकते हैं: अपने परीक्षण डेटाबेस में

-- 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 में निर्दिष्ट होना चाहिए।

संबंधित मुद्दे