Mysql2:: Ошибка: неправильное строковое значение
У меня есть приложение rails, работающее в режиме производства, но внезапно эта ошибка появилась сегодня, когда пользователь попытался сохранить запись.
Mysql2::Error: Incorrect string value
Подробнее (из журнала производства):
Parameters: {"utf8"=>"â<9c><93>" ...
Mysql2::Error: Incorrect string value: '\xC5\x99\xC3\xA1k
Mysql2::Error: Incorrect string value: '\xC5\x99\xC3\xA1k
Теперь я увидел некоторые решения, которые требовали сбросить базы данных и воссоздать их, но я не могу этого сделать.
Теперь mysql показывает это:
mysql> show variables like 'char%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.04 sec)
Что не так и как я могу его изменить, поэтому у меня нет проблем с любыми символами?
Также: эта проблема разрешима с помощью javascript? Преобразовать его перед отправкой?
Спасибо
Ответы
Ответ 1
проблема вызвана кодировкой вашей серверной части mysql. Вы можете настроить вручную, например:
ALTER TABLE your_database_name.your_table CONVERT TO CHARACTER SET utf8
или отбросьте таблицу и заново создайте ее, как:
rake db:drop
rake db:create
rake db:migrate
ссылки:
fooobar.com/questions/148008/...
fooobar.com/questions/148008/...
UPDATE
первая команда влияет только на указанную таблицу, если вы хотите изменить все таблицы в базе данных, вы можете сделать это как
ALTER DATABASE databasename CHARACTER SET utf8 COLLATE utf8_general_ci;
ссылка:
fooobar.com/questions/19544/...
Ответ 2
Вы можете использовать миграцию, подобную этой, чтобы преобразовать ваши таблицы в utf8:
class ConvertTablesToUtf8 < ActiveRecord::Migration
def change_encoding(encoding,collation)
connection = ActiveRecord::Base.connection
tables = connection.tables
dbname =connection.current_database
execute <<-SQL
ALTER DATABASE #{dbname} CHARACTER SET #{encoding} COLLATE #{collation};
SQL
tables.each do |tablename|
execute <<-SQL
ALTER TABLE #{dbname}.#{tablename} CONVERT TO CHARACTER SET #{encoding} COLLATE #{collation};
SQL
end
end
def change
reversible do |dir|
dir.up do
change_encoding('utf8','utf8_general_ci')
end
dir.down do
change_encoding('latin1','latin1_swedish_ci')
end
end
end
end
Ответ 3
Мне удалось сохранить emojis (который занимает 4 байта), следуя этому сообщению :
Rails 4, MySQL и Emoji (Mysql2::Error: Incorrect string value error.
)
Вы можете подумать, что безопасно вставлять большинство данных utf8 в в mysql, когда вы указали, что кодировка utf-8
. К сожалению, однако, вы ошибаетесь. Проблема в том, что набор символов utf8 занимает 3 байта при хранении в столбце VARCHAR. Эможи-персонажи, на с другой стороны, возьмите 4 байта.
Решение состоит из двух частей:
Измените кодировку таблицы и полей:
ALTER TABLE `[table]`
CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_bin,
MODIFY [column] VARCHAR(250)
CHARACTER SET utf8mb4 COLLATE utf8mb4_bin
Сообщите об этом адаптеру mysql2
:
development:
adapter: mysql2
database: db
username:
password:
encoding: utf8mb4
collation: utf8mb4_unicode_ci
Надеюсь, это поможет кому-то!
Затем мне пришлось перезагрузить приложение, и оно сработало.
Обратите внимание, что некоторые emojis будут работать без этого исправления, в то время как некоторые не будут:
- ➡️ Работает
- 🔵 Не работает, пока я не применил исправление, описанное выше.
Ответ 4
Необходимо изменить CHARACTER SET
и COLLATE
для уже созданной базы данных:
ALTER DATABASE databasename CHARACTER SET utf8 COLLATE utf8_unicode_ci;
Или нужно было создать базу данных с заранее заданными параметрами:
CREATE DATABASE databasename CHARACTER SET utf8 COLLATE utf8_general_ci;
Ответ 5
Кажется, что проблема кодирования при получении данных из базы данных. Попробуйте добавить ниже в файл database.yml
encoding: utf8
Надеюсь, что это решит вашу проблему.
Ответ 6
Кроме того, если вы не хотите делать изменения в структуре базы данных, вы можете выбрать сериализацию поля, о котором идет речь.
class MyModel < ActiveRecord::Base
serialize :content
attr_accessible :content, :title
end