JSON と Python のマッピング
JSON と Python の dict は以下のようにマッピングされている。
JSON | Python |
---|---|
object | dict |
array | list |
string | unicode |
number (int) | int, long |
number(real) | float |
true | True |
false | False |
null | None |
そのため、JSON を json.loads()
でパースして、そのまま dynamo.put_item()
で登録すると前述の型で登録される。この際に float 型があると下記のように怒られる。
Float types are not supported. Use Decimal types instead.
Python の float はそのままでは DynamoDB に登録できないのである。
代わりに Decimal で登録する必要がある。
Float ではなく Decimal として登録するには?
Float を Decimal にマッピングさせる必要がある。
例えば以下の様なデータを登録するとする。
{"Timestamp": "20160323T203501.000+0900", "x": -0.279938, "y": -0.754028, "z": -0.607758 }
JSON をパースする際に下記のように parse_float=decimal.Decimal
をつければよい。
import json
import boto3
import decimal
#...省略
item = json.loads(json_data, parse_float=decimal.Decimal)
dynamo = boto3.resource('dynamodb').Table('ThisIsJustTest')
dynamo.put_item(Item = item)
補足
Python 公式にも記載されていたが、ぐぐってもすぐに情報が出なかったので記事にした。
parse_float, if specified, will be called with the string of every JSON float to be decoded. By default, this is equivalent to float(num_str). This can be used to use another datatype or parser for JSON floats (e.g. decimal.Decimal).
json.loads(s[, encoding[, cls[, object_hook[, parse_float[, parse_int[, parse_constant[, object_pairs_hook[, **kw]]]]]]]])
AWS のドキュメントにもサラッとのっていた。
https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/gettingstartedguide/GettingStarted.Python.02.html
Decimal から戻すとき
以下のようなやり方紹介されている。
https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/gettingstartedguide/GettingStarted.Python.03.html
http://stackoverflow.com/questions/1960516/python-json-serialize-a-decimal-object