Переключите mysql на mysql2 gem, чтобы все Unicode испортилось - PullRequest
2 голосов
/ 18 апреля 2011

До того, как мое приложение было на Heroku и использовало mysql gem.Когда я перемещаю эти данные в свою собственную базу данных mysql и переключаюсь на gem mysql2, мой символ uncode отображается в их необработанной форме utf8.

С другой стороны, если я обновляю данные unicode в базу данных с помощью gem mysql2,затем переключитесь обратно на mysql gem, я получу вопросительный знак, если я запрашиваю Unicode-символ.

Из моих наблюдений, mysql gem выдает идентичный вывод в сравнении с клиентской утилитой mysql (на моем Ubuntu), а mysql2 - нет.

Есть ли способ заставить gem mysql2 читать данные и кодировать так же, как это делает клиент mysql?(и, следовательно, таким же образом, что и MySQL Gem)

Ответы [ 4 ]

3 голосов
/ 19 апреля 2011

У меня были похожие проблемы при переносе данных в Heroku и обратно, вы должны иметь возможность принудительного кодирования в database.yml с помощью

encoding: UTF8

Следует также отметить, что Heroku по умолчанию использует PostgreSQL, даже если вы включили самоцвет mysql.

0 голосов
/ 03 июля 2012

Я написал миграцию, чтобы исправить это, как и во всех случаях, ваш пробег может отличаться.

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
0 голосов
/ 19 мая 2011

Мое решение - выгрузить данные в файл .sql, использовать конвертер Юникод, чтобы преобразовать этот файл .sql в правильную кодировку, а затем вывести его обратно на сервер.

0 голосов
/ 16 мая 2011

Хорошо, у меня тоже было много проблем с этим, но я сделал грязное решение. Дело в том, что в Rails 2 гем 'mysql', кажется, принимает строку в кодировке latin1 из базы данных mysql (по умолчанию) как utf 8.

mysql2 больше не делает этого. Загрузка из activerecord в rails2 с гемом mysql показывает правильный вывод, но в rails3 гем mysql больше не работает. Для этого перейдите к консоли в 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) для любого экземпляра activerecord.

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

Позволит вам обновить данные вашего экземпляра. Конечно, вы можете сделать цикл самостоятельно. :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...