はじめに
Dockerを使用して立てたMySQLのコンテナ上に自分以外の方がNestJSとtypeORMで書いてくれたmigrationコードを実行してデータベースを構築したところダミーデータ作成時に日本語の部分が以下のエラーで弾かれました。
ERROR 1366 (HY000): Incorrect string value:
このエラーに対してどのように対処したかの一例を述べます。 (ぽんこつすぎて6時間もってかれましたー。。。)
ここで紹介するのはデータベースの文字コードを変えて再起動するだけでは解決できなかった事例です。
使用していたdocker-compose.ymlファイル
作成したデータベースの情報がコンテナremove時に失われないようにローカル環境に保持されるようにvolumesを設定しています。
version: '3'
services:
mysql:
image: mysql:5.7
volumes:
- "./mysql:/var/lib/mysql"
restart: always
environment:
- MYSQL_ROOT_PASSWORD=設定するパスワード
- MYSQL_DATABASE=データベース名
ports:
- 3306:3306
phpmyadmin:
image: phpmyadmin/phpmyadmin
environment:
- PMA_ARBITRARY=1
- PMA_HOST=mysql
- PMA_USER=root
- PMA_PASSWORD=設定するパスワード
ports:
- 8080:80
volumes:
- /sessions
とりあえず詳しいこと抜きで解決した方法
- MySQL初期設定用のmy.cnfを文字コードがutf8mb4で動作するように記述し作成し任意の場所に配置
- 作成したmy.cnfがdocker-compose.ymlでコンテナ上の/etc/my.cnfとして配置されるようにvolumesを記述
- エラーが発生しているデータベースを削除
- 同名データベースを作成
- migrateを実行(ここはmigrateコードなどの自動生成コードを作っていない場合はもう一度地道にテーブルを作り直してください)
やったこと
[Dockerの公式MySQLの文字コードをutf8mb4に設定する]
(https://qiita.com/Suzuki09/items/c05664c7c0c08a19cebe)
↑の記事を参考にした
こちらの記事では、commandでmysqldを実行するように書いてあるがここでもエラーが出て実行できなかった。
どうやらmysqldコマンドはrootユーザーでは使用できないようです。なのでちょっとめんどくさかったですが、my.cnfを作業ディレクトリで作成しvolumesで紐付け"my.cnf:/etc/my.cnf" でローカルに作成したmy.cnfをコンテナ上に配置するようにしました。
とりあえず/etcの下に配置すれば動作する感じです。
my.cnfの内容で必須なのはcharacter-set-serverとdefault-character-setっぽい
尚、上の記事を参考に作成したmy.cnfではうまく動かなかったです。なので結局参考にしたのはこれ
MySQLで文字コードを直す時のmy.cnfの書き方 - 鶏口牛後な日々
結果的に作成したmy.cnfは以下のとおりです。
[mysqld]
character-set-server=utf8mb4
explicit-defaults-for-timestamp=1
general-log=1
general-log-file=/var/log/mysql/mysqld.log
[mysql]
default-character-set=utf8mb4
出来上がったdocker-compose.ymlは以下の通り
version: '3'
services:
mysql:
image: mysql:5.7
volumes:
- "./mysql:/var/lib/mysql"
- "./my.cnf:/etc/my.cnf" ←--- これを追加しました!
restart: always
environment:
- MYSQL_ROOT_PASSWORD=設定するパスワード
- MYSQL_DATABASE=データベース名
ports:
- 3306:3306
phpmyadmin:
image: phpmyadmin/phpmyadmin
environment:
- PMA_ARBITRARY=1
- PMA_HOST=mysql
- PMA_USER=root
- PMA_PASSWORD=設定するパスワード
ports:
- 8080:80
volumes:
- /sessions
すでにデータベースを作成しているときはデータベース自体に文字コードを設定してしまっておりMySQLの設定を変更しても適用されないため、データベースの設定を変更する
MySQLの日本語文字化け回避!文字コードを確認&変更する方法 | サービス | プロエンジニア
これをやってもまだ動かなかった
データベースのテーブルを確認するとcollationが例のutf8じゃないやつになっていた。
なので、データベース自体を一度ドロップしてデータベースからテーブルまですべて削除し、migrate(データベースとテーブルの作成)しなおしたところcollationが変更され日本語がINSERTできるようになりました。
まとめ
データベースの初期設定さえしっかりやっていればこんなことにはならなかったですね。。。
とりあえず、dockerでも自身のコンピュータのOS上でもMySQLなりpostgressなり動かす場合にはデータベースやらテーブルやらを作成する前にプロジェクトにあったもの(日本のプロジェクトの場合はだいたいutf8でしょうか)の初期設定を行ってはならないということですね。