BioErrorLog Tech Blog

試行錯誤の記録

エラー対処: Object of type datetime is not JSON serializable | Python

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変換できないオブジェクトを扱う方法をまとめました。

分かってしまえば簡単ですが、分かるまでには色々とハマってしまいました。

同じ状況に陥ったどなたかの役に立てば幸いです。

[関連記事]

www.bioerrorlog.work

www.bioerrorlog.work

www.bioerrorlog.work

参考

json — JSON encoder and decoder — Python 3.11.4 documentation

python - How to overcome "datetime.datetime not JSON serializable"? - Stack Overflow

Working With JSON Data in Python – Real Python