Python3 MysqlDBからMariaDBに絵文字を保存しようとすると”Warning: (1366, “Incorrect string value: ‘\xF0\x9F\x98\x8A\xF0\x9F…’ for column ‘lunch’ at row 1”)”のようなエラーが発生して、保存できなかった。経緯を調べると、現在のUTF-8は4byte利用しているが、MariaDBは歴史的経緯により3byteのUTF-8までしか対応していなかった。絵文字で拡張された部分が4byte利用するということのようだ。
この場合以下の対応が必要となる。
- MariaDBの設定
- データベースのcharcterset更新
- Python3 MysqlDBのcharcterset変更
MariaDBの設定
/etc/my.confまたは、各項目を/etc/my.conf.d/[server.conf|client.conf]に分けて記述する。
[client]
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
[mysqld]
character-set-client-handshake = FALSE
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
設定後mariadbを再起動すれば設定完了です。再起動後以下のコマンドで確認してください。以下のようになっていれば設定は成功しています。
mysql> SHOW VARIABLES WHERE Variable_name LIKE 'character\_set\_%' OR Variable_name LIKE 'collation%';
+--------------------------+--------------------+
| Variable_name | Value |
+--------------------------+--------------------+
| character_set_client | utf8mb4 |
| character_set_connection | utf8mb4 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | utf8mb4 |
| character_set_server | utf8mb4 |
| character_set_system | utf8 |
| collation_connection | utf8mb4_unicode_ci |
| collation_database | utf8mb4_unicode_ci |
| collation_server | utf8mb4_unicode_ci |
+--------------------------+--------------------+
10 rows in set (0.00 sec)
データベースCharsetの変更
以下のように各データベース・テーブル等に設定してください。例のSQL分はDB名やテーブル名がサンプルになっています。特にカラムの場合にはカラム名が変更されてしまうので、注意してください。
# 各DBで行う:
ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
# 各テーブル(テーブルにcharasetが設定されていたら):
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
# 各カラム(設定していたら):
ALTER TABLE table_name CHANGE column_name column_name VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Pytho3 MysqlDBの設定変更
connect時にcharsetをutf8としていたものを、utf8mb4に変更してください。
self.db = MySQLdb.connect( host=Mconfig.strDBhost, db=self.strDBname, user=self.strDBuser, passwd=self.strDBpass, charset="utf8mb4")
以上で完了です。絵文字が保存できるようになったことを確認してみてください。