AWS IoTからDynamoDBへRulesを使ってデータ投入したらPayload部がデータ変換されて焦った話


AWS IoTを通してDynamoDBへデータ投入を試みます。2015年後半に突然の仕様変更をしたみたいで、DynamoDBに保存されるパターンが変わってしまったので、メモ。

準備

AWS IoT側の設定

RulesでDynamoDBの方に流れるようにしておきます。

Rulesは以下の設定をしておきます。

カテゴリ 内容
Query SELECT * FROM '/test/#'
Action

DynamoDB側の設定

次の設定をしておきます。

カテゴリ 内容 タイプ
プライマリパーティションキー id 文字列
プライマリソートキー timestamp 文字列

*timestampは受信時刻用

送付用データ

次のデータを流してみます。送付のトピックは「/test/sensor_result」

{
  "sensor_id": 101,
  "temperature": 25.4,
  "humidity": 40.5,
  "timestamp": '2016-09-11T11:00:00'
}

送付結果

データ送付をすると、DynamoDBにデータが投入されるのですが、こんな感じで送ったデータがpayload_rawとしてエンコードされた状態で保存されてしまっていました。これでは投入したデータを使おうとしても使えません。少し焦りました。
※ちなみにpayload_rawはBase64にエンコードされていました。

データ取得すれば問題はなかった

なんのことはない、Pythonなどでデータ取得した際には特に問題なく表示されました。DynamoDB側に表示モードみたいなものがあれば焦らずに済んだのに。

一応確認するためにLambdaでスクリプトを組みました。

import boto3
import logging
from boto3.dynamodb.conditions import Key

logger = logging.getLogger()
logger.setLevel(logging.INFO)

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('AWSTest')

def handle_request(event, context):
    response = table.query(
        KeyConditionExpression=Key('id').eq('sensor_result')
    )
    logger.info("response: {}".format(response))

結果はこんな感じ。

[INFO]  2016-09-11T13:08:27.232Z    d3c0e7af-7820-11e6-801d-230a9d8bdc12    response: {u'Count': 4, u'Items': [{u'timestamp': u'1473595931501', u'payload_raw': Binary('{
  "sensor_id": 101,
  "temperature": 25.4,
  "humidity": 40.5,
  "timestamp": \'2016-09-11T11:00:00\'
}')