2015年2月19日木曜日

Google App Engine : ndb のデータを JSON 化する + json.dumps を date 対応させる


このエントリーをはてなブックマークに追加
MyModel.query().fetch() などで ndb.Model を取得した後、ndb.Model の to_dict() 関数を使用して json 化します。

to_dict() には key が含まれないので、key が必要な場合には明示的に追加します。


fetched_list = MyModel.query().fetch()
json_without_keyid = json.dumps([c.to_dict() for c in fetched_list ])
json_with_keyid = json.dumps([dict(c.to_dict(), **dict(id=c.key.id())) for c in fetched_list ])


追記

数字や文字列のみの場合上記のコードで問題なかったのですが、
DateProperty を使用していた Model は

File "C:\Python27\lib\json\encoder.py", line 184, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: datetime.date(2015, 2, 20) is not JSON serializable

というエラーで json 化に失敗してしまいました。
そこで、以下のように、date オブジェクトの場合の処理を追加した JSONEncoder を作成し、対応を加えました。datetime の場合なども同じような方法で対応できるはずです。


from datetime import date

class JSONDateEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, date):
            return obj.isoformat()
        return json.JSONEncoder.default(self, obj)


fetched_list = MyModel.query().fetch()
json_without_keyid = json.dumps([c.to_dict() for c in fetched_list ], cls=JSONDateEncoder)
json_with_keyid = json.dumps([dict(c.to_dict(), **dict(id=c.key.id())) for c in fetched_list ], cls=JSONDateEncoder)


参考:AppEngine Making ndb models json serializableHow to overcome “datetime.datetime not JSON serializable” in python?

0 件のコメント:

コメントを投稿