はじめに
こんにちは~。さきやです。
今回は、DjangoのSQLite3データベースをMySQLサーバーに移行する作業で1日くらいハマりました。
原因は文字コードの照合順序だったんですが、意外なところに落とし穴がありました。
初投稿なので、読みにくいところもあるかもですがご了承下さい。
それでは本編どうぞ
環境
Windows(Ubuntu 20.04)
Docker 4.20
Django 3.2
MySQL 8系
※今回はDockerの環境は関係ありませんが、参考までに載せています!
経緯
データベースを移行する際、Django で下記のようなコマンドをよく実行しますよね。
#1. 現在のデータベースを json 形式のファイルで出力する (-eオプションなどをつけてエラー回避することが多いですが、詳しい説明は割愛します。)
python manage.py dumpdata > dump.json
#2. 1で出力した dump.json を他のデータベースに読み込ませる
python manage.py loaddata dump.json
僕はDB移行が初体験だったので、ドキドキしながら移行作業を続けてたところ、
発生したエラーがこれ。
django.db.utils.IntegrityError: Problem installing fixture '***/dump.json': Could not load ***.******(pk=**): (1062, "Duplicate entry '**' for key '*****'")
「エラーに出してるデータが重複しちゃうからデータ挿入できないよー」って言ってますね。
そして、このエラー自体は10年以上前からあるようで解決ソースはたくさん出てきました。
が、どれも解決には至らず…。
↓僕のエラー吐いていたデータ
魔女ッ子メグちゃん
そもそも重複しているデータなんて見当たらなかったので、「なんのこと?」って状態でした。
それでハマってしまったのが今回記事を書いた経緯です。
原因
単純なことが原因でした!
僕は趣味でアニメのレビューサイトを制作しているのですが
今回は、データベースに格納していた2つの「アニメタイトルの文字列」が原因でした。
魔女ッ子メグちゃん
魔女っ子メグちゃん
この2つのタイトルの違い分かりますか?
「魔女」の後ろに「っ」と「ッ」が入ってますよね。
原因これです。
要は、「カタカナとひらがなを区別する文字コード(照合順序)」を指定してなかったんですね。
おそらく僕と同じエラーでハマっている人はエラー文に
『ひらがな又はカタカナが含まれる文字列』が含まれていると思います。
解決方法
ということで、
『カタカナとひらがなを区別する文字コード(照合順序)』ってなんぞや~って思った方。
正解は、こちらです!
utf8_general_ci
これを Docker の MySQL コンテナの起動時コマンドで指定してやれば、、、
version: '3.7'
services:
・・・略・・・
database:
image: mysql
# 僕のDocker環境では character-set-server=utf8mb4 としているので、collation-server=utf8mb4_general_ci となる
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci --default_authentication_plugin=mysql_native_password
env_file:
- database-docker-compose.env
解決(´・ω・`)
※ my.cnf ファイルに直接設定を書き込んでいる場合は、そのファイルに collation-server=使用している文字コード
_general_ci のように追記してください。
まとめ
今回はかなり珍しいケースかもしれませんが
英語の記事ばかり読んでいて、日本語特有の思わぬ落とし穴に気づきませんでした(笑)
あと、文字コードってカタカナとひらがな区別するもの(照合順序)があるんだな~っと勉強になりました・・・。
今回 Qiita 初投稿だったので読みづらいところもあったと思いますが、
日本語の記事がパッと見当たらなかったので自分で記事にしてみました。
参考になれば幸いです(´・ω・`)
ありがとうございました。
参考記事: