Django3ではJSONFieldがサポートされた。Django2までは、いろいろな JSONFieldがライブラリとして実装されており挙動とサポート範囲が異なって いた。それぞれのJSONFieldがMySQL上ではどのように定義されるのかを確認し た。
検証環境
ソフトウェア | バージョン |
---|---|
Python | Python3.6 |
Database | MySQL 5.7 |
Django2
Django3
model
Fooというモデルを定義し、それぞれのJSONFieldを用いたカラムを定義した。
カラム名 | Fieldクラス | 備考 |
---|---|---|
the_json | django-jsonfield.JSONField | |
native_json | django.db.models.JSONField | Django2では使用不可 |
backport_json | django_jsonfield_backport.models.JSONField |
(jango3版のモデル定義)
MySQLでのテーブル定義
django-jsonfield.JSONFieldはMySQL上ではlogntxt型で定義される。 django.db.models.JSONFieldはMySQL上ではjson型で定義される。 django_jsonfield_backport.models.JSONFieldはdjango.db.models.JSONField のバックポート版なのでjson型で定義される。
django-jsonfield.JSONFieldをdjango.db.models.JSONFieldに変更すると MySQL上の型も変わってしまうので型の変更及びデータ自体も変更になる。
Python上の型 | MySQL上の型 |
---|---|
django-jsonfield.JSONField | longtext |
django.db.models.JSONField | json |
django_jsonfield_backport.models.JSONField | json |
show create table foo_foo; +---------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +---------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | foo_foo | CREATE TABLE `foo_foo` ( `id` int(11) NOT NULL AUTO_INCREMENT, `the_json` longtext NOT NULL, `native_json` json NOT NULL, `backport_json` json NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 | +---------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.01 sec)
MySQLのjson型
MySQL上でのjson型は次のような振る舞いをする
- JSON 値は文字列として書き込まれる。
- JSONドキュメントの格納に必要な領域はLONGBLOBやLONGTEXTとほぼ同じとなる。
- JSON値を必要とするコンテキストで使用される文字列を解析し、JSONとして有効でない場合はエラーを生成する。
- MySQL 8.0.13より前は、NULL以外のデフォルト値を含めることはできない。