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"

これに対する対処法を整理します。

The English translation of this post is here.

背景

まずはエラーに遭遇した状況を説明します。

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

参考