【Django】「MySQLdb._exceptions.IntegrityError: (1062, “Duplicate entry ~」エラー対処法

PythonのフレームワークDjangoで使用しているデータベースの移行のお話です。

Djangoは初期アプリの推奨DBとしてSQLiteを指定しています。
しかし、それをMySQLに変更したいという人も多いはずです。

dumpでデータを取得した後に、loaddataをするとエラーになり、
以下のようにduplicateと表示されています。

MySQLdb._exceptions.IntegrityError: (1062, “Duplicate entry ‘aaa’ for key ‘id'”)

今回はそのエラーの解消が目的です。

「MySQLdb._exceptions.IntegrityError: (1062, “Duplicate entry ~」エラー対処法

Duplicateエラーの原因

さて、このエラーですが、そもそもDuplicateとは「重複している」という単語です。

dumpしたデータなのに重複とかあるの?

と思われるかもしれませんが、実はSQLiteからMySQLに移行する際、以下のようなデータは同じものとして扱われることがあります。

  • aaa
  • Aaa
  • AAA

つまり、英語の大文字と小文字を区別しないということです。
これはMySQLがデフォルトで設定している照合順序「utf8mb4_general_ci」が原因です。

「utf8mb4_general_ci」は大文字小文字を区別しません。
よって上のような3つのデータはすべて同じものと見なされ、重複しているから入れられないよ、と怒られているわけですね。

Duplicateエラーの解決策

MySQLの照合順序を変更すればOKです。
「utf8mb4_general_ci」から「utf8mb4_bin」に変更しましょう。

移行先のサーバーにphpMyAdminがあるならそこから照合順序を変えてしまえばOKです。
もしないなら、特定のカラムに対して照合順序を変更するコマンドを打ちましょう。

use データベース名
ALTER TABLE テーブル名 MODIFY COLUMN カラム名 varchar (255) COLLATE ‘utf8mb4_bin’;

これで大文字と小文字が区別され、データの移行が正常に出来るようになります。