MENU

Boto3のTypeDeserializerを使用してDynamoDB Streamsイベントをパースする

DynamoDB Streamのパース、ずっと自前でやっていたんだが、実はライブラリでデシリアライザが用意されていることを「DynamoDB JSONの型変換をboto3だけで行ってみる | DevelopersIO」で知った。。。これを使うとDynamoDB Streamのパースも楽にできる。

テストデータとセットであると便利に思ったので、ChatGPT-4に聞いてみた。

目次

イントロ

Boto3のTypeDeserializerは、DynamoDBのデータ型をPythonの標準のデータ型に変換するのに役立ちます。これは、DynamoDB Streamsのイベントを処理する際に特に便利です。この記事では、TypeDeserializerの基本的な使い方と、それを使用してDynamoDB Streamsイベントをパースする方法について説明します。

TypeDeserializerの基本

TypeDeserializerクラスは、DynamoDBのレスポンスをパースするための便利なツールです。これはDynamoDBからのレスポンスをPythonの標準的なデータ型に変換します。以下に基本的な使用方法を示します。

from boto3.dynamodb.types import TypeDeserializer

deserializer = TypeDeserializer()

# DynamoDBのデータ
dynamodb_data = {
    'S': 'Hello, world!'
}

# データをデシリアライズ
deserialized_data = deserializer.deserialize(dynamodb_data)

print(deserialized_data)  # 'Hello, world!'

ここでは、DynamoDBの文字列型('S')をPythonの文字列にデシリアライズしています。

なお、DynamoDBの数値データ型('N')は、Boto3のTypeDeserializerを使用してデシリアライズされるとき、Pythonのdecimal.Decimal型になります。

これはDynamoDBが数値を浮動小数点数として保存し、それがそのままの精度で保存されることを保証するためです。Pythonの標準的なintfloat型を使用すると、特に大きな数値や非常に小さな数値の場合に精度が失われる可能性があります。そのため、decimal.Decimal型が使用されます。

DynamoDB Streamsイベントのパース

DynamoDB Streamsイベントは、テーブルに変更があったときに発行されます。これらのイベントには、変更前後の項目の詳細やイベントの種類(INSERT、MODIFY、REMOVE)など、役立つ情報が含まれています。

以下は、TypeDeserializerを使用してDynamoDB Streamsイベントをパースする例です。

from boto3.dynamodb.types import TypeDeserializer

def parse_dynamodb_stream_event(event): 
    deserializer = TypeDeserializer() 
    for record in event['Records']: 
        dynamodb = record['dynamodb'] 
        
        # 変更前の項目をパース
        if 'OldImage' in dynamodb: 
            old_image = {k: deserializer.deserialize(v) for k, v in dynamodb['OldImage'].items()} 
        else: 
            old_image = None 
         
        # 変更後の項目をパース
        if 'NewImage' in dynamodb: 
            new_image = {k: deserializer.deserialize(v) for k, v in dynamodb['NewImage'].items()} 
        else: 
            new_image = None 
        
        print(f"Event Name: {record['eventName']}") 
        print(f"Old Image: {old_image}") 
        print(f"New Image: {new_image}\n")

この関数は、DynamoDB Streamsイベントの各レコードの"OldImage"と"NewImage"をパースしてPythonのデータ型に変換します。これにより、変更前後の項目データを簡単に利用することができます。

なお、DynamoDB Streamのイベント例は以下です。

{
  "Records": [
    {
      "eventID": "1",
      "eventName": "INSERT",
      "eventVersion": "1.0",
      "eventSource": "aws:dynamodb",
      "awsRegion": "us-west-2",
      "dynamodb": {
        "Keys": {
          "Id": {
            "N": "101"
          }
        },
        "NewImage": {
          "Message": {
            "S": "New item!"
          },
          "Id": {
            "N": "101"
          }
        },
        "StreamViewType": "NEW_AND_OLD_IMAGES",
        "SequenceNumber": "111",
        "SizeBytes": 26
      },
      "eventSourceARN": "arn:aws:dynamodb:us-west-2:account-id:table/ExampleTableWithStream/stream/2015-06-27T00:48:05.899"
    },
    {
      "eventID": "2",
      "eventName": "MODIFY",
      "eventVersion": "1.0",
      "eventSource": "aws:dynamodb",
      "awsRegion": "us-west-2",
      "dynamodb": {
        "Keys": {
          "Id": {
            "N": "101"
          }
        },
        "NewImage": {
          "Message": {
            "S": "This item has changed"
          },
          "Id": {
            "N": "101"
          }
        },
        "OldImage": {
          "Message": {
            "S": "New item!"
          },
          "Id": {
            "N": "101"
          }
        },
        "StreamViewType": "NEW_AND_OLD_IMAGES",
        "SequenceNumber": "222",
        "SizeBytes": 59
      },
      "eventSourceARN": "arn:aws:dynamodb:us-west-2:account-id:table/ExampleTableWithStream/stream/2015-06-27T00:48:05.899"
    },
    {
      "eventID": "3",
      "eventName": "REMOVE",
      "eventVersion": "1.0",
      "eventSource": "aws:dynamodb",
      "awsRegion": "us-west-2",
      "dynamodb": {
        "Keys": {
          "Id": {
            "N": "101"
          }
        },
        "OldImage": {
          "Message": {
            "S": "This item has changed"
          },
          "Id": {
            "N": "101"
          }
        },
        "StreamViewType": "NEW_AND_OLD_IMAGES",
        "SequenceNumber": "333",
        "SizeBytes": 38
      },
      "eventSourceARN": "arn:aws:dynamodb:us-west-2:account-id:table/ExampleTableWithStream/stream/2015-06-27T00:48:05.899"
    }
  ]
}

以上が、Boto3のTypeDeserializerを使用してDynamoDB Streamsイベントをパースする方法です。

寸評

テストデータを出してくれるのが神。

以下がChatGPT-4にした質問。

  • boto3のTypeDeserializerの使い方を教えて
  • DynamoDB Streamのeventをパースするのにも使える?
  • DynamoDB Streamのテストデータを出して
  • ここまでのことを記事としてまとめてください。
  • (追加)このデシリアライザを使うと、数値はDecimalになりますか、それともintになりますか、それともfloatになりますか?

最初にある程度正解知ってるからよかった。

目次