AWS Lambda for Python 2.7 の Inexact: None エラーに対応する

AWS Lambda for Python 2.7 環境で開発をしている際に、

TypeError: Float types are not supported. Use Decimal types instead.

Inexact: None

といったエラーを直せず苦戦したので、その対応をメモします。

f:id:ketancho_jp:20171111044631p:plain

背景

 Lambda for Python 2.7 で、DynamoDB からデータを取得する処理を書いていました。DynamoDBのテーブルは、

  • string 型の datetime カラム(PK)
  • string 型の text カラム(GSI①:Partition Key)
  • number 型の num カラム(GSI①:Sort Key)

という定義で、

datetime | text | num
======================
20170101 | abcd | 1.1
20170201 | abcd | 1.5
20170301 | xyzz | 1.6
20170401 | abcd | 1.8

のようなイメージになります。

 text を Partition Key、 num をソートキーとした GSI(Global Secondary Index)を張り、「 textabcdnum1.3 から 1.9 の間にあるレコード」を取得できるようにしています。

問題点

この処理を、

TBL.query(
    IndexName='text-num-index',
    KeyConditionExpression=Key('text').eq("abcd") & Key('num').between(1.3, 1.9)
)

としたのですが、

TypeError: Float types are not supported. Use Decimal types instead.

というエラーが発生してしまいました。そこで、

TBL.query(
    IndexName='text-num-index',
    KeyConditionExpression=Key('text').eq("abcd") & Key('num').between(decimal.Decimal(1.3), decimal.Decimal(1.9))
)

としたのですが、

Inexact: None

となってしましました。桁落ちみたいなことになっているのでしょうか。

解決策

How can I store 30.40 in DynamoDb? · Issue #665 · boto/boto3 · GitHub

こちらを参考に下記のように Decimal の引数を文字列に変換することで解決しました。

TBL.query(
    IndexName='text-num-index',
    KeyConditionExpression=Key('text').eq("abcd") &Key('num').between(Decimal(str(1.3)), Decimal(str(1.9))) )