У меня есть промежуточный сайт Rails, работающий на MySQL 5.0.32-Debian.
На этом конкретном сайте все мои таблицы используют кодировку utf8 / utf8_general_ci.
Внутри этой базы данных у меня есть данные, которые выглядят так:
mysql> select * from currency_types limit 1,10;
+------+-----------------+---------+
| code | name | symbol |
+------+-----------------+---------+
| CAD | Canadian Dollar | $ |
| CNY | Chinese Yuan | å…ƒ |
| EUR | Euro | € |
| GBP | Pound | £ |
| INR | Indian Rupees | ₨ |
| JPY | Yen | ¥ |
| MXN | Mexican Peso | $ |
| USD | US Dollar | $ |
| PHP | Philippine Peso | ₱ |
| DKK | Denmark Kroner | kr |
+------+-----------------+---------+
Вот проблема, с которой я столкнулся
При постановке (с сайтом db и Rails, запущенным в окне debian) символы для символов отображаются правильно при отображении из Rails. Например, китайский юань отображается в моем браузере как 元, а не как å… ƒ, как это показано в базе данных.
Когда я загружаю эти данные на свою локальную машину для разработки OS X и запускаю базу данных и Rails локально, я вижу представление изнутри БД (å… ƒ) в моем браузере, а не символ 元, как я вижу при постановке.
Отладку я сделал
Я обеспечил, чтобы все заголовки Content-Type возвращались как utf8 с каждого веб-сервера (локального, промежуточного).
Мой локальный сервер mysql и промежуточный сервер настроены на использование utf8 в качестве кодировки по умолчанию. Я использую "набор имен 'utf8'" перед тем, как звонить.
Я даже могу подключиться к своей промежуточной базе данных с моего хоста OS X Rails, и я все еще вижу символы å… ƒ, представляющие юань. Тогда я предполагаю, что, возможно, есть проблема с моим локальным клиентом mysql, но я не могу понять, в чем проблема.
Возможно, это может дать ключ к разгадке
Чтобы сделать это еще более запутанным, если я вставлю символ 元 в базу данных на моем локальном компьютере, я увижу это в веб-браузере нормально. --- ДА, если я вставлю этот же символ в свою промежуточную базу данных, я получу? отметьте это место на странице моего промежуточного сайта Rails.
Кроме того, локально на моей рельсовой машине с OS X, если я использую «установить имена 'latin1'» перед своими запросами, все символы возвращаются правильно. Раньше у меня были эти таблицы как latin1 - может ли это быть проблемой?
Кто-нибудь, пожалуйста, помогите мне здесь, я схожу с ума, пытаясь понять, что не так!






АГА! Кажется, у меня раньше была некоторая табличная информация, закодированная в latin1, и я тупо изменил базы данных на utf8 без преобразования.
Выполнение следующей исправленной таблицы currency_types:
mysqldump -u root -p --opt --default-character-set=latin1 --skip-set-charset DBNAME > DBNAME.sql
mysql -u root -p --default-character-set=utf8 DBNAME < DBNAME.sql
Теперь мне просто нужно убедиться, что другой контент, сгенерированный после переключателя latin1> utf8, не испорчен этим :(
Спасибо! Сегодня утром я немного почесал в затылке, и это оказалось решением для базы данных, созданной до меня!
Пользователь Windows, который получает только сообщения «доступ запрещен», должен изменить DBNAME.sql на % домашний путь% \ DBNAME.sql как для mysqldump-, так и для mysql-вызовов. И спасибо Subimage!
Чистый гений. Молодец @Subimage. Ваш диагноз о том, что база данных была преобразована в utf8 без преобразования данных в отдельные таблицы, - это именно то, что произошло в нашем случае. Ваше решение тоже работает очень хорошо.
Я читал о многих других проблемах с utf8-rails3-mysql, прежде чем обнаружил этот тикет, который оказался именно тем, что произошло с сайтом, над которым я работаю.
Спас день для меня. Спасибо.
У меня нет части $ KCODE, но у меня есть "encoding: utf8" во всех файлах конфигурации. Кажется, моя проблема заключалась в том, что у меня в базе данных был смешанный контент. Итак, я хранил символы latin-1, но пытался прочитать их как utf8
Я видел ваш ответ после публикации этого сообщения. В любом случае, спасибо за указание на эту ошибку. Я видел эту ошибку во многих случаях
Есть ли у вас эти две строки в вашем database.yml в соответствующем разделе?
encoding: utf8
collation: utf8_general_ci
не знал, что файл yml может иметь строку сопоставления, но да, у меня есть кодирующая строка ...
Почему рекомендуется использовать utf8_unicode_ci вместо utf8_general_ci?
@mauriciomdea Хороший вопрос: по сути, utf8_general_ci немного быстрее, но не так точен. Лучше всего использовать utf8_unicode_ci. Подробнее здесь: stackoverflow.com/questions/766809/…
Другой простой подход - установить тип кодирования с помощью оператора SQL Alter. Вы можете сделать это, используя приведенный ниже сценарий bash.
for t in $(mysql --user=root --password=admin --database=DBNAME -e "show tables";);do echo "Altering" $t;mysql --user=root --password=admin --database=DBNAME -e "ALTER TABLE $t CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;";done
украшенный
for t in $(mysql --user=root --password=admin --database=DBNAME -e "show tables";);
do
echo "Altering" $t;
mysql --user=root --password=admin --database=DBNAME -e "ALTER TABLE $t CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;";
done
Моя БД уже была установлена по умолчанию на utf8, но я столкнулся с той же проблемой.
Также после добавления следующего обычного метатега проблема все еще существовала:
<meta http-equiv = "Content-Type" content = "text/html; charset=utf-8" />
Затем я создал специальный connection.php, чтобы гарантировать, что вся связь с MySQL установлена на кодировку utf8. Обратите внимание, что в UTF8 в - нет mysqli_set_charset($bd, 'utf8')!
Вот мой Connection.php:
<?php
$mysql_hostname = "localhost";
$mysql_user = "username";
$mysql_password = "password";
$mysql_database = "dbname";
$prefix = "";
$bd = mysqli_connect($mysql_hostname, $mysql_user, $mysql_password) or die("Could not connect database");
mysqli_select_db($bd, $mysql_database) or die("Could not select database");
if (!mysqli_set_charset($bd, 'utf8')) {
exit() ;
}
?>
Другой файл php:
<?php
//Include database connection details
require_once('connection.php');
//Enter code here...
//Create query
$qry = "SELECT * FROM subject";
$result = mysqli_query($bd, $qry);
?>
//Other stuff
Для Rails запустите следующий фрагмент кода в консоль rails. Он сгенерирует sql для всех таблиц. Затем войдите в mysql и выполните скопированный sql из консоли rails. Это изменит кодировку всех таблиц.
schema = File.open('db/schema.rb', 'r').read
rows = schema.split("\n")
table_name = nil
rows.each do |row|
if row =~ /create_table/
table_name = row.match(/create_table "(.+)"/)[1]
puts "ALTER TABLE `#{table_name}` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;"
end
end
Это не способ Rails, попробуйте вместо этого использовать миграции.
Вы можете сгенерировать миграцию способом Rails, чтобы изменить тип сопоставления в ваших базах данных:
rails generate migration ChangeDatabaseCollation
Затем вы можете отредактировать сгенерированный файл и вставить:
def change
# for each table that will store the new collation execute:
execute "ALTER TABLE my_table CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci"
end
И запускаем миграцию:
rake db:migrate
Вы также можете принудительно применить новую сортировку к вашему database.yml:
development:
adapter: mysql2
encoding: utf8
collation: utf8_general_ci
Для получения дополнительной информации о миграции Rails:
http://edgeguides.rubyonrails.org/active_record_migrations.html
Для получения дополнительной информации о типах сопоставления:
Да вот в чем проблема. но когда вы установили соединение на latin1, это выглядело нормально, потому что он выполнял тот же перевод. У меня была эта проблема, но я не мог воссоздать базу данных. Поэтому я изменил phpMyAdmin на использование соединения latin1, затем экспортировал (так что теперь экспортированные данные были правильными), затем удалил этот взлом и повторно импортировал. Данные исправлены. Подробности здесь: omegadelta.net/2010/11/23/…