aoishiの備忘録

備忘録

Djangoで文字コードutf8mb4でMySQLに接続する方法

はじめに

Django文字コードがutf8mb4のMySQLデータベースを利用するためのメモです。

絵文字を含むデータを使うために文字コードがutf8mb4のデータベースを作成したのですが、クライアント側の文字コード設定を忘れてしまい、レコード追加時に下記のエラーが発生してしまったので設定方法をまとめました。

django.db.utils.InternalError: (1366, "Incorrect string value: '\\xF0\\x9F\\x8C\\xBF\\x0Ai...' for column 'message' at row 1")

環境

方法

MySQL接続に必要なパッケージのインストール

Python実装のMySQLクライアントライブラリである PyMySQL をインストールします。

$ pip install PyMySQL

文字コードがutf8mb4のデータベースを作成

文字コードがutf8mb4のデータベースを作成します。

mysql> CREATE DATABASE {{ db_name }} CHARACTER SET utf8mb4;

コレーションを明示的に指定する場合は下記のように作成します。

mysql> CREATE DATABASE {{ db_name }} CHARACTER SET utf8mb4 COLLATE {{ collation_name }};
文字コード一覧確認方法

参考までに、MySQLで扱える文字コード一覧とデフォルトのコレーション確認方法です。

mysql> SHOW CHARACTER SET;
+----------+---------------------------------+---------------------+--------+
| Charset  | Description                     | Default collation   | Maxlen |
+----------+---------------------------------+---------------------+--------+
~~~
| utf8     | UTF-8 Unicode                   | utf8_general_ci     |      3 |
~~~
| utf8mb4  | UTF-8 Unicode                   | utf8mb4_general_ci  |      4 |
~~~
41 rows in set (0.00 sec)

utf8mb4のコレーション一覧確認方法

utf8mb4で利用可能なコレーション一覧の確認方法です。

mysql> SHOW COLLATION WHERE CHARSET = "utf8mb4";                             
+------------------------+---------+-----+---------+----------+---------+
| Collation              | Charset | Id  | Default | Compiled | Sortlen |
+------------------------+---------+-----+---------+----------+---------+
| utf8mb4_general_ci     | utf8mb4 |  45 | Yes     | Yes      |       1 |
| utf8mb4_bin            | utf8mb4 |  46 |         | Yes      |       1 |
| utf8mb4_unicode_ci     | utf8mb4 | 224 |         | Yes      |       8 |
~~~
26 rows in set (0.00 sec)

settings.pyでutf8mb4の文字コードを設定

settings.pyのDATABASESの設定を修正し、OPTIONSに'charset': 'utf8mb4'を追加します。

charsetを明示的に指定しない場合、Djangoはutf8でデータベースに接続します。

import pymysql
pymysql.install_as_MySQLdb()
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': '{{ db_name }}',
        'USER': '{{ user_name }}',
        'PASSWORD': '{{ user_password }}',
        'HOST': '{{ db_host }}',
        'PORT': {{ db_port }},
        'OPTIONS': {
            'charset': 'utf8mb4',
        },
    }
}

まとめ

DjangoMySQL文字コードutf8mb4で絵文字を含む文字列を扱うための設定方法をまとめました。

データベース側とクライアント側で文字コードを合わせることでエラーは無事解消しました。

参考資料

https://github.com/PyMySQL/PyMySQL:html

MySQL :: MySQL 5.7 Reference Manual :: 13.1.11 CREATE DATABASE Syntax

Databases | Django documentation | Django