2

私のアプリがHerokuにあり、mysql gemを使用する前。そのデータを自分の mysql データベースに移行し、mysql2 gem に切り替えると、コード化されていない文字が未加工の utf8 形式で表示されます。

一方、mysql2 gem を使用して Unicode データをデータベースに更新してから mysql gem に戻すと、Unicode 文字を照会すると疑問符が返されます。

私の観察によると、mysql gem は (私の Ubuntu の) mysql クライアント ユーティリティと比較して同一の出力を生成しますが、mysql2 は生成しません。

mysql2 gem に、mysql クライアントと同じ方法でデータを読み取ってエンコードするように指示する方法はありますか? (したがって、mysql gem と同じ方法で)

4

4 に答える 4

3

Heroku との間でデータを移行するときに同様の問題が発生しました。database.yml でエンコーディングを強制できるはずです。

encoding: UTF8

また、mysql gem を含めたとしても、Heroku はデフォルトで PostgreSQL を使用することもポイントです。

于 2011-04-18T22:14:40.347 に答える
0

私の解決策は、データを .sql ファイルにダンプし、Unicode コンバーターを使用してその .sql ファイルを適切なエンコーディングに変換してから、サーバーにダンプすることです。

于 2011-05-19T11:16:49.760 に答える
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
于 2012-07-03T06:18:05.167 に答える
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

これで、任意のアクティブ レコード インスタンスで update_instance_from_backup(instance) を呼び出すことができます。

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

インスタンス データを更新できます。もちろん、自分でループすることもできます。:)

于 2011-05-16T00:12:15.513 に答える