はじめに
例えば、DynamoDBでint/float的な数値データを扱うと、データがdecimalとして取り出されます。こういったデータが含まれるようなqueryやgetしたアイテムに対してpythonの標準的なjson.dumpsを実行すると、変換できない型により例外が発生しましす。で、いつもこの対処方法を忘れるのでメモを残します。(類似でDatetime型で同様のことが起きます)
json.dumpsが型エラーで失敗したら変換関数を用意することで対処できます。
そもそも
json.dumpsには引数としてdefaultを指定することできます。ここで変換用の関数をセットすることで対象外の型を自分でハンドルしてお好みの型に変換できます。
以下公式からの抜粋
default を指定する場合は関数を指定して、この関数はそれ以外では直列化できないオブジェクトに対して呼び出されます。 その関数は、オブジェクトを JSON でエンコードできるバージョンにして返すか、さもなければ TypeError を送出しなければなりません。 指定しない場合は、 TypeError が送出されます。
実際には?
変換用関数を用意します。
from decimal import Decimal
def decimal_to_int(obj):
if isinstance(obj, Decimal):
return int(obj)
json.dumpを実行する際には、
json.dumps(your_val, default=decimal_to_int)
として、defaultの引数に変換関数をセットするだけです。
今回はdecimalを変換するようにしか書いてませんが、型変換関数に想定される型チェック、変換ロジックを用意しておけばマルチの型対応も対応可能です。datetimeはstrftimeで書式つけの文字列にして返すとか。
というわけで、当たり前の用に使ってる関数もちゃんと成り立ちを理解できると便利ですね。というわけで、きちんと理解したい方はこちらをご確認下さい。
とても短い記事ですがいつも忘れるので、ほぼ自分用のメモです。
他のやり方は?
simplejsonなどは対応できる型が多いようです。自分は使ったことないですが。
もしAWS Lambdaで使いたい場合は標準パッケージに含まれないために、自分でパッケージに追加するか、Lambda レイヤーとして登録する必要があります。