MySQL 8.0のクライアントでMySQL 5.7のサーバーに接続するとcharsetが設定されないかもしれない
↑こちらで詳しい説明がある。現象としてはページの件名の通り、文字コードがクライアント側から指定できない。
Ubuntu を 18 -> 20 にアップグレードして、その上で動いている Django から MySQL 5.7 RDS のデータを取得した時に、日本語がすべて ???????? と表示された。
$ cat /etc/issue
Ubuntu 20.04.2 LTS \n \l
$ apt list --installed | grep mysql
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
default-libmysqlclient-dev/focal,now 1.0.5ubuntu2 amd64 [installed]
libmysqlclient-dev/focal-updates,focal-security,now 8.0.26-0ubuntu0.20.04.2 amd64 [installed,automatic]
libmysqlclient21/focal-updates,focal-security,now 8.0.26-0ubuntu0.20.04.2 amd64 [installed,automatic]
mysql-client-core-8.0/focal-updates,focal-security,now 8.0.26-0ubuntu0.20.04.2 amd64 [installed]
mysql-common/focal,now 5.8+1.0.5ubuntu2 all [installed,automatic]
ためしに、
./manage.py dbshell
してみて、
mysql> show variables like "%chara%";
すると
mysql> show variables like "%chara%";
+--------------------------+-------------------------------------------+
| Variable_name | Value |
+--------------------------+-------------------------------------------+
| character_set_client | latin1 |
| character_set_connection | latin1 |
| character_set_database | utf8mb4 |
| character_set_filesystem | binary |
| character_set_results | latin1 |
| character_set_server | latin1 |
| character_set_system | utf8 |
| character_sets_dir | /rdsdbbin/mysql-5.7.33.R2/share/charsets/ |
+--------------------------+-------------------------------------------+
8 rows in set (0.01 sec)
こうなる。
本来は、character_set_client などの文字コードが utf8mb4 にならなければいけない。実際、ubuntu18 で同じことをすると、utf8mb4 になる。
また、このキャラクタセットが latin1
になる現象は、 ubuntu18 上の mysql
コマンドで、 --default-character-set=utf8mb4
をつけてみたり、/etc/mysql/conf.d/mysql.cnf
の中に 文字コードの設定を書いても一切変わらない。
mysql に接続後、
SET NAMES utf8mb4
すると、日本語は化けなくなる。
ちなみに実運用時は無駄なSQLは出したくないため、プロダクション環境でこれは行わないが、Django であれば DB設定をこのようにすることで実現できそう。
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
...
'OPTIONS': {
'charset': 'utf8mb4',
'init_command': 'set names utf8mb4',
},
},
}
この状態なら、クライアント側の設定では(上記 SET NAMES utf8mb4 以外では)回避できなそうなので、サーバ側で文字コードを設定する。RDS なら、パラメータグループで
character_set_client
character_set_connection
character_set_database
character_set_results
character_set_server
これらをすべて utf8mb4
に設定すれば良い。
実際は utf8mb4 以外の文字コードを使うことって通常無いので、最初からやっとけよって気もするが。
これらのパラメータは dynamic 属性のものなので、設定したら RDS の再起動なしに適用できる。
コメント