Pythonのjsonモジュールを利用してjson変換する際に発生した、下記のエラーの対処法をまとめます。
"Object of type datetime is not JSON serializable"
はじめに
jsonモジュールを使うと、Python上でjsonを扱うことが出来ます。 しかし、json対応されていない形式は、そのままでは扱うことが出来ません。
今回、datetime
形式が含まれたデータをjson変換しようとした際、以下のエラーに遭遇しました。
"Object of type datetime is not JSON serializable"
これに対する対処法を整理します。
背景
まずはエラーに遭遇した状況を説明します。
AWS のPython SDK: Boto3のdescribe_instances()
を用いてEC2インスタンス情報をdict形式で取得し、それをjson.dumps()
でjson変換しました。
import json import boto3 ec2_client = boto3.client('ec2') response = ec2_client.describe_instances() json.dumps(response)
すると以下のエラーが吐かれます。
"errorMessage": "Object of type datetime is not JSON serializable", "errorType": "TypeError",
json.dumps()
の引数に渡したdictの中に、json変換できないdatetime
形式が含まれている、というエラーです。
以下、このエラーに対する2つの対処法を紹介します。
対処法
defaultパラメータ
まず、json.dumps()
がもつdefault
パラメータについて簡単に説明します。
(対処法は両方ともdefault
を使います)
default
パラメータの説明をドキュメントから引用すると、
If specified, default should be a function that gets called for objects that can’t otherwise be serialized. It should return a JSON encodable version of the object or raise a TypeError. If not specified, TypeError is raised.
json変換できないオブジェクトに対して適用されるfunctionを指定できる、とのことです。
このdefault
に何かしらのfunctionを与えてあげることで、json変換できない形式を、json変換可能な形式にすることが出来ます。
対処法1:string変換
一つ目の簡単で雑な対処法としては、このdefault
パラメータにstr
を与えることです。
json.dumps(response,default=str)
str()
関数を与えることで、json変換できない形式のオブジェクトはすべてstringに変換されます。
かなり雑ですが、簡単にエラーを回避できます。
対処法2:カスタム変換
2つ目はもう少し丁寧な対処法です。
default
に渡すfunctionを自分で定義します。
例えば以下のように、datetime
およびdate
形式のオブジェクトをisoformat
に変換するjson_serial()
を定義し、default
に指定します:
from datetime import date, datetime def json_serial(obj): if isinstance(obj, (datetime, date)): return obj.isoformat() raise TypeError (f'Type {obj} not serializable') json.dumps(response,default=json_serial)
このやり方ならdatetime
だけでなく、他の形式についても同様に形式を指定して変換が可能です。
特に理由がなければ、こちらのやり方の方が良いでしょう。
おわりに
以上、json変換できないオブジェクトを扱う方法をまとめました。
分かってしまえば簡単ですが、分かるまでには色々とハマってしまいました。
同じ状況に陥ったどなたかの役に立てば幸いです。
[関連記事]
参考
json — JSON encoder and decoder — Python 3.11.4 documentation
python - How to overcome "datetime.datetime not JSON serializable"? - Stack Overflow