紙一重の積み重ね

アラフォーのエンジニアがなれる最高の自分を目指して、学んだことをこつこつ情報発信するブログです。

"Object of type 'Decimal' is not JSON serializable"が発生したときの対処法 #Python3 #AWS #dynamodb

f:id:yokoyantech:20180613171711p:plain

やりたいこと

Python3を使って、DynamoDBのqueryを使って取得したJSONデータをPostgreSQLにINSERTしたい

実行環境

  • AWS DynamoDB
  • AWS Lambda
    • Python3.6
    • psycopg2.7.4
  • AWS RDS(PostgreSQL9.6.6)

発生したエラー

jsonを使ってダンプした結果、INSERT時にエラー発生。

import json

cur.execute(insert_query,json.dumps(hogehoge))
"errorMessage": "Object of type 'Decimal' is not JSON serializable",
"errorType": "TypeError"

解決法

DynamoDBで使われているDecimal型をJSONに変換する。

import simplejson as json

json.dumps(hogehoge)

そのまま書き換えると、lambda実行時にimportできないと怒られてしまう。

Unable to import module 'lambda_function': No module named 'simplejson'

解決法

simplejsonを使う。

まずはLambda関数の直下にインストールする。 -t .もしくは、--target .でカレントディレクトリにインストールできる。

$ pip install simplejson -t .
import simplejson

simplejson.dumps(hogehoge)

Lambda関数をzipに固めてAWSにアップロードする。

$ zip -r upload.zip *

参考情報その1

qiita.com

参考情報その2

http://narusemotoki.tumblr.com/post/81653528336/pythonでdecimalを含むdictをjson文字列に変換するにはsimplejsonを使う
narusemotoki.tumblr.com

参考情報その3

simplejson — JSON encoder and decoder — simplejson 3.15.0 documentation

によると、jsonよりもパフォーマンス上の利点があるとのこと。

ただ、以下の記事を見る限り、jsonのほうが早い模様。 ujsonはもっと早い。

http://blog.dataweave.in/post/87589606893/json-vs-simplejson-vs-ultrajson
blog.dataweave.in