Проблемы MySQL в UTF8 на Rails - проблемы с кодированием с помощью utf8_general_ci

У меня есть промежуточный сайт 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 - может ли это быть проблемой?

Кто-нибудь, пожалуйста, помогите мне здесь, я схожу с ума, пытаясь понять, что не так!

Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
19
0
17 891
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Ответ принят как подходящий

АГА! Кажется, у меня раньше была некоторая табличная информация, закодированная в 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, не испорчен этим :(

Да вот в чем проблема. но когда вы установили соединение на latin1, это выглядело нормально, потому что он выполнял тот же перевод. У меня была эта проблема, но я не мог воссоздать базу данных. Поэтому я изменил phpMyAdmin на использование соединения latin1, затем экспортировал (так что теперь экспортированные данные были правильными), затем удалил этот взлом и повторно импортировал. Данные исправлены. Подробности здесь: omegadelta.net/2010/11/23/…

William Denniss 23.11.2010 07:15

Спасибо! Сегодня утром я немного почесал в затылке, и это оказалось решением для базы данных, созданной до меня!

Cymen 14.01.2011 20:38

Пользователь Windows, который получает только сообщения «доступ запрещен», должен изменить DBNAME.sql на % домашний путь% \ DBNAME.sql как для mysqldump-, так и для mysql-вызовов. И спасибо Subimage!

Alex B. 11.01.2012 04:13

Чистый гений. Молодец @Subimage. Ваш диагноз о том, что база данных была преобразована в utf8 без преобразования данных в отдельные таблицы, - это именно то, что произошло в нашем случае. Ваше решение тоже работает очень хорошо.

Sujoy Gupta 11.07.2012 05:41

Я читал о многих других проблемах с utf8-rails3-mysql, прежде чем обнаружил этот тикет, который оказался именно тем, что произошло с сайтом, над которым я работаю.

Jesse Clark 08.04.2013 06:57

Спас день для меня. Спасибо.

NM Pennypacker 06.08.2014 20:22
  1. Проблема могла быть в вашем MySQL-клиенте, который не поддерживает UTF-8.
  2. Ваша локальная конфигурация установки OSX ruby ​​могла не указать правильные конфигурации. У вас должно быть "encoding: utf8" в "config / database.yml" для базы данных MySQL. У вас должно быть «$ KCODE = 'u'» в «config / environment.rb» для среды ruby.

У меня нет части $ KCODE, но у меня есть "encoding: utf8" во всех файлах конфигурации. Кажется, моя проблема заключалась в том, что у меня в базе данных был смешанный контент. Итак, я хранил символы latin-1, но пытался прочитать их как utf8

Subimage 06.12.2008 12:10

Я видел ваш ответ после публикации этого сообщения. В любом случае, спасибо за указание на эту ошибку. Я видел эту ошибку во многих случаях

yrcjaya 06.12.2008 13:35

Есть ли у вас эти две строки в вашем database.yml в соответствующем разделе?

encoding: utf8
collation: utf8_general_ci

не знал, что файл yml может иметь строку сопоставления, но да, у меня есть кодирующая строка ...

Subimage 09.12.2008 03:23

Почему рекомендуется использовать utf8_unicode_ci вместо utf8_general_ci?

mauriciomdea 27.11.2015 17:02

@mauriciomdea Хороший вопрос: по сути, utf8_general_ci немного быстрее, но не так точен. Лучше всего использовать utf8_unicode_ci. Подробнее здесь: stackoverflow.com/questions/766809/…

Joshua Pinter 04.03.2018 23:33

Другой простой подход - установить тип кодирования с помощью оператора 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, попробуйте вместо этого использовать миграции.

mauriciomdea 27.11.2015 17:00

Вы можете сгенерировать миграцию способом 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

Для получения дополнительной информации о типах сопоставления:

http://collation-charts.org/

Другие вопросы по теме