2011-04-18 27 views
2

在我的應用程序在Heroku之前,並使用MySQL的寶石。 當我將這些數據遷移到我自己的mysql數據庫並切換到mysql2 gem時,我的uncode字符以其原始utf8格式查看。將mysql切換到mysql2 gem導致所有的unicode混亂

另一方面,如果我使用mysql2 gem更新unicode數據到數據庫,然後切換回mysql gem,如果查詢unicode字符,我會回到問號。

從我的觀察來看,mysql gem與mysql客戶端實用程序(在我的Ubuntu上)產生相同的輸出,而mysql2沒有。

有沒有辦法告訴mysql2 gem讀取數據和使用相同的方式編碼mysql客戶端呢? (從而以相同的方式MySQL的寶石一樣)

回答

0

我的解決方案是將數據轉儲到.sql文件中,使用unicode轉換器將該.sql文件轉換爲正確的編碼,然後將其轉儲回服務器。

+0

你一直在使用哪種轉換器? – marko 2012-03-09 19:01:41

+0

我使用的是unikey轉換器,如果您使用越南語,這可能只會有幫助。 – 2012-03-10 12:45:43

3

遷移數據時,並從Heroku的我有類似的問題,你應該能夠迫使編碼在database.yml中與

encoding: UTF8 

指向也是因爲Heroku默認使用PostgreSQL,即使你已經包含了mysql gem。

+0

此設置已經存在於我的database.yml中。我的問題也發佈在mysql2 gem的問題列表上:https://github.com/brianmario/mysql2/issues/149。不知道爲什麼,但現在mysql和mysql2 gem都生成了unicode文本的utf8(raw格式)8-x – 2011-04-19 15:15:37

+1

我認爲'encoding:utf8'(小寫)格式是正確的格式。 – rovitulli 2016-02-24 01:43:29

0

好吧,我也遇到了很多問題,但做了一個骯髒的解決方案。事情是,在Rails 2中,'mysql'gem似乎接受來自mysql數據庫(缺省值)的latin1編碼字符串作爲utf 8.

mysql2不再這樣做。使用mysql gem在rails2中從activerecord加載顯示正確的輸出,但在rails3中,mysql gem不再工作。因此,轉到rails2中的控制檯,並使用以下代碼片段。我使用數據庫的副本,以防你想回去。

def update_instance_from_backup(current_instance) 
    begin 
    ActiveRecord::Base.establish_connection(
     :adapter => "mysql", 
     :host  => "localhost", 
     :username => "...", 
     :password => "...", 
     :database => "database_backup" 
    ) 
    attributes = current_instance.class.find(current_instance.id).attributes 
    ActiveRecord::Base.establish_connection(
     :adapter => "mysql2", 
     :host  => "localhost", 
     :username => "...", 
     :password => "...", 
     :database => "database", 
     :encoding => "utf8" 
    ) 
    rescue 
    else 
    current_instance.update_attributes attributes 
    puts "#{current_instance.class.name} #{current_instance.id} (dd. #{current_instance.updated_at}) updated" 
    end 
end 

現在,您可以在任何activerecord實例上調用update_instance_from_backup(instance)。

foo = Foo.find(3) 
update_instance_from_backup(foo) 

是否允許您更新實例數據。你當然可以自己做一個循環。 :)

0

我寫了一個遷移來解決這個問題,就像所有的事情一樣,你的里程可能會有所不同。

class FixUnicodeCrap < ActiveRecord::Migration 
    def up 
    r = ActiveRecord::Base.run_sql(<<sql 
select TABLE_NAME, COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, CHARACTER_MAXIMUM_LENGTH, DATA_TYPE from INFORMATION_SCHEMA.COLUMNS 
    where TABLE_SCHEMA = database() 
     and DATA_TYPE in ('varchar','text') 
     and CHARACTER_SET_NAME = 'latin1'  
sql 
) 
    r.each do |row| 
     target_type = 'BLOB' 
     if row[5] == 'varchar' 
     target_type = "VARBINARY(#{row[4]})" 
     end 
     null = row[3] == 'YES' ? "NULL" : "NOT NULL" 
     if (row[0] != 'page_views') # if you need to skip any dbs, change this 
     execute "ALTER TABLE #{row[0]} MODIFY #{row[1]} #{target_type};" 
     execute "ALTER TABLE #{row[0]} MODIFY #{row[1]} #{row[2]} CHARACTER SET utf8 #{null};" 
     end 
    end 
    end 

    def down 
    end 
end 


module EasySql 
    def self.included(base) 
    base.extend(Extensions) 
    end 

    module Extensions 
    def run_sql(sql, *args) 
     connection.execute(
     sanitize_sql_array([sql] + args) 
    ) 
    end 
    end 
end 
ActiveRecord::Base.send :include, EasySql