BioErrorLog Tech Blog

試行錯誤の記録

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

Pythonのjsonモジュールを利用してjson変換する際に発生した、以下のエラーの対処法です。

"Object of type datetime is not JSON serializable"


はじめに

おはよう。@bioerrorlogです。

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変換できないオブジェクトを扱う対処法を簡単に書きました。

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

同じ状況に陥った誰かの役に立てば何よりです。


関連記事

Pythonで自作したゲームの製作記録です。 www.bioerrorlog.work


ググりテクのひとつ、英語圏でGoogle検索する方法を書きました。 www.bioerrorlog.work


参考

json — JSON encoder and decoder — Python 3.9.1 documentation

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

Working With JSON Data in Python – Real Python