DynamoDB Streamで渡されるeventデータの表示タイプごとの内容をまとめてみた

Lambdaの実行トリガーにしているDynamoDB Streamの表示タイプ(StreamViewType)を変更する必要が生じ、表示タイプの変更前後でLambdaに渡されるeventデータの内容がどのように変わるのか調べたのでまとめました。
2020.02.13

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、CX事業本部の若槻です。

案件でLambdaの実行トリガーにしているDynamoDB Streamの表示タイプ(StreamViewType)を変更する必要が生じ、表示タイプの変更前後でLambdaに渡されるeventデータの内容がどのように変わるのか調べたのでまとめました。

※2022/11/25:指摘を受けてデータをレコードと表現していた記述をアイテムに修正

実際に調べてみた

DynamoDB Streamには以下の4種類の表示タイプ(= StreamViewType)があります。

項番 表示タイプ StreamViewType
1 キーのみ - 変更された項目のキー属性のみ。 KEYS_ONLY
2 新しいイメージ – 変更後に表示される項目全体。 NEW_IMAGE
3 古いイメージ – 変更前に表示されていた項目全体。 OLD_IMAGE
4 新旧イメージ - 項目の新しいイメージと古いイメージの両方。 NEW_AND_OLD_IMAGES

上記それぞれの表示タイプの時に、テーブル上のアイテムに対して下記の操作が行われた際にLambdaへ渡されるeventデータを確認します。

  • アイテム新規作成(INSERT
  • 既存アイテムに属性新規追加(MODIFY
  • 既存アイテムの既存キーの値を変更(MODIFY
  • 既存アイテムを削除(REMOVE

1. キーのみ - 変更された項目のキー属性のみ。(KEYS_ONLY)

アイテム新規作成(INSERT

  • 新規作成したアイテム
{
  "id": "0001",
  "name": "クラスメソッド"
}
  • DynamoDB StreamからLambdaに渡されたeventデータ
{
    "Records": [
        {
            "eventID": "ecbdabbe517afd39c63d59b684e4dd29",
            "eventName": "INSERT",
            "eventVersion": "1.1",
            "eventSource": "aws:dynamodb",
            "awsRegion": "ap-northeast-1",
            "dynamodb": {
                "ApproximateCreationDateTime": 1581430684,
                "Keys": {
                    "id": {
                        "S": "0001"
                    }
                },
                "SequenceNumber": "66400000000000679556686",
                "SizeBytes": 6,
                "StreamViewType": "KEYS_ONLY"
            },
            "eventSourceARN": "arn:aws:dynamodb:ap-northeast-1:123456789012:table/demo-table/stream/2020-02-11T14:04:42.274"
        }
    ]
}

既存アイテムに新規追加(MODIFY

  • 変更前のアイテム
{
  "id": "0001",
  "name": "クラスメソッド"
}
  • 変更後のアイテム
{
  "id": "0001",
  "name": "クラスメソッド",
  "NumberOfOffice": "12"
}
  • DynamoDB StreamからLambdaに渡されたeventデータ
{
    "Records": [
        {
            "eventID": "e877377e0f65d49e44c10b55937f2873",
            "eventName": "MODIFY",
            "eventVersion": "1.1",
            "eventSource": "aws:dynamodb",
            "awsRegion": "ap-northeast-1",
            "dynamodb": {
                "ApproximateCreationDateTime": 1581431167,
                "Keys": {
                    "id": {
                        "S": "0001"
                    }
                },
                "SequenceNumber": "66500000000000679728066",
                "SizeBytes": 6,
                "StreamViewType": "KEYS_ONLY"
            },
            "eventSourceARN": "arn:aws:dynamodb:ap-northeast-1:123456789012:table/demo-table/stream/2020-02-11T14:04:42.274"
        }
    ]
}

既存アイテムの既存属性の値を変更(MODIFY

  • 変更前のアイテム
{
  "id": "0001",
  "name": "クラスメソッド",
  "NumberOfOffice": "12"
}
  • 変更後のアイテム
{
  "id": "0001",
  "name": "クラスメソッド",
  "NumberOfOffice": "13"
}
  • DynamoDB StreamからLambdaに渡されたeventデータ
{
    "Records": [
        {
            "eventID": "cc931269bce71c56a40b6097f0024320",
            "eventName": "MODIFY",
            "eventVersion": "1.1",
            "eventSource": "aws:dynamodb",
            "awsRegion": "ap-northeast-1",
            "dynamodb": {
                "ApproximateCreationDateTime": 1581431429,
                "Keys": {
                    "id": {
                        "S": "0001"
                    }
                },
                "SequenceNumber": "66600000000000679797672",
                "SizeBytes": 6,
                "StreamViewType": "KEYS_ONLY"
            },
            "eventSourceARN": "arn:aws:dynamodb:ap-northeast-1:123456789012:table/demo-table/stream/2020-02-11T14:04:42.274"
        }
    ]
}

既存アイテムを削除(REMOVE

  • 削除前のアイテム
{
  "id": "0001",
  "name": "クラスメソッド",
  "NumberOfOffice": "13"
}
  • DynamoDB StreamからLambdaに渡されたeventデータ
{
    "Records": [
        {
            "eventID": "2f43aec272ebb622bef375201c18c533",
            "eventName": "REMOVE",
            "eventVersion": "1.1",
            "eventSource": "aws:dynamodb",
            "awsRegion": "ap-northeast-1",
            "dynamodb": {
                "ApproximateCreationDateTime": 1581431648,
                "Keys": {
                    "id": {
                        "S": "0001"
                    }
                },
                "SequenceNumber": "66700000000000679854178",
                "SizeBytes": 6,
                "StreamViewType": "KEYS_ONLY"
            },
            "eventSourceARN": "arn:aws:dynamodb:ap-northeast-1:123456789012:table/demo-table/stream/2020-02-11T14:04:42.274"
        }
    ]
}

2. 新しいイメージ – 変更後に表示される項目全体。(NEW_IMAGE)

アイテム新規作成(INSERT

  • 新規作成したアイテム
{
  "id": "0001",
  "name": "クラスメソッド"
}
  • DynamoDB StreamからLambdaに渡されたeventデータ
{
    "Records": [
        {
            "eventID": "676e30baa54502616bba1b8eae26631c",
            "eventName": "INSERT",
            "eventVersion": "1.1",
            "eventSource": "aws:dynamodb",
            "awsRegion": "ap-northeast-1",
            "dynamodb": {
                "ApproximateCreationDateTime": 1581434173,
                "Keys": {
                    "id": {
                        "S": "0001"
                    }
                },
                "NewImage": {
                    "name": {
                        "S": "クラスメソッド"
                    },
                    "id": {
                        "S": "0001"
                    }
                },
                "SequenceNumber": "269000000000000666115010",
                "SizeBytes": 37,
                "StreamViewType": "NEW_IMAGE"
            },
            "eventSourceARN": "arn:aws:dynamodb:ap-northeast-1:123456789012:table/demo-table/stream/2020-02-11T15:05:06.716"
        }
    ]
}

既存アイテムに属性新規追加(MODIFY

  • 変更前のアイテム
{
  "id": "0001",
  "name": "クラスメソッド"
}
  • 変更後のアイテム
{
  "id": "0001",
  "name": "クラスメソッド",
  "NumberOfOffice": "12"
}
  • DynamoDB StreamからLambdaに渡されたeventデータ
{
    "Records": [
        {
            "eventID": "646fd448e28b9aa0e7f3a9f280ff3863",
            "eventName": "MODIFY",
            "eventVersion": "1.1",
            "eventSource": "aws:dynamodb",
            "awsRegion": "ap-northeast-1",
            "dynamodb": {
                "ApproximateCreationDateTime": 1581433878,
                "Keys": {
                    "id": {
                        "S": "0001"
                    }
                },
                "NewImage": {
                    "NumberOfOffice": {
                        "S": "12"
                    },
                    "name": {
                        "S": "クラスメソッド"
                    },
                    "id": {
                        "S": "0001"
                    }
                },
                "SequenceNumber": "268700000000000666076013",
                "SizeBytes": 53,
                "StreamViewType": "NEW_IMAGE"
            },
            "eventSourceARN": "arn:aws:dynamodb:ap-northeast-1:123456789012:table/demo-table/stream/2020-02-11T15:05:06.716"
        }
    ]
}

既存アイテムの既存属性の値を変更(MODIFY

  • 変更前のアイテム
{
  "id": "0001",
  "name": "クラスメソッド",
  "NumberOfOffice": "12"
}
  • 変更後のアイテム
{
  "id": "0001",
  "name": "クラスメソッド",
  "NumberOfOffice": "13"
}
  • DynamoDB StreamからLambdaに渡されたeventデータ
{
    "Records": [
        {
            "eventID": "094c41fd462e6418419d62eb088cfe7f",
            "eventName": "MODIFY",
            "eventVersion": "1.1",
            "eventSource": "aws:dynamodb",
            "awsRegion": "ap-northeast-1",
            "dynamodb": {
                "ApproximateCreationDateTime": 1581434041,
                "Keys": {
                    "id": {
                        "S": "0001"
                    }
                },
                "NewImage": {
                    "NumberOfOffice": {
                        "S": "13"
                    },
                    "name": {
                        "S": "クラスメソッド"
                    },
                    "id": {
                        "S": "0001"
                    }
                },
                "SequenceNumber": "268800000000000666097698",
                "SizeBytes": 53,
                "StreamViewType": "NEW_IMAGE"
            },
            "eventSourceARN": "arn:aws:dynamodb:ap-northeast-1:123456789012:table/demo-table/stream/2020-02-11T15:05:06.716"
        }
    ]
}

既存アイテムを削除(REMOVE

  • 削除前のアイテム
{
  "id": "0001",
  "name": "クラスメソッド",
  "NumberOfOffice": "13"
}
  • DynamoDB StreamからLambdaに渡されたeventデータ
{
    "Records": [
        {
            "eventID": "8ceb2aca8da5185e5e79ab3ccde3156f",
            "eventName": "REMOVE",
            "eventVersion": "1.1",
            "eventSource": "aws:dynamodb",
            "awsRegion": "ap-northeast-1",
            "dynamodb": {
                "ApproximateCreationDateTime": 1581434102,
                "Keys": {
                    "id": {
                        "S": "0001"
                    }
                },
                "SequenceNumber": "268900000000000666105180",
                "SizeBytes": 6,
                "StreamViewType": "NEW_IMAGE"
            },
            "eventSourceARN": "arn:aws:dynamodb:ap-northeast-1:123456789012:table/demo-table/stream/2020-02-11T15:05:06.716"
        }
    ]
}

3. 古いイメージ – 変更前に表示されていた項目全体。(OLD_IMAGE)

アイテム新規作成(INSERT

  • 新規作成したアイテム
{
  "id": "0001",
  "name": "クラスメソッド"
}
  • DynamoDB StreamからLambdaに渡されたeventデータ
{
    "Records": [
        {
            "eventID": "0e5db66b7c1c0d36f76580d79859d0ec",
            "eventName": "INSERT",
            "eventVersion": "1.1",
            "eventSource": "aws:dynamodb",
            "awsRegion": "ap-northeast-1",
            "dynamodb": {
                "ApproximateCreationDateTime": 1581434970,
                "Keys": {
                    "id": {
                        "S": "0001"
                    }
                },
                "SequenceNumber": "321600000000000749678042",
                "SizeBytes": 6,
                "StreamViewType": "OLD_IMAGE"
            },
            "eventSourceARN": "arn:aws:dynamodb:ap-northeast-1:123456789012:table/demo-table/stream/2020-02-11T15:20:25.062"
        }
    ]
}

既存アイテムに属性新規追加(MODIFY

  • 変更前のアイテム
{
  "id": "0001",
  "name": "クラスメソッド"
}
  • 変更後のアイテム
{
  "id": "0001",
  "name": "クラスメソッド",
  "NumberOfOffice": "12"
}
  • DynamoDB StreamからLambdaに渡されたeventデータ
{
    "Records": [
        {
            "eventID": "7c89c3d5e4f40070f6d5d01465208b7f",
            "eventName": "MODIFY",
            "eventVersion": "1.1",
            "eventSource": "aws:dynamodb",
            "awsRegion": "ap-northeast-1",
            "dynamodb": {
                "ApproximateCreationDateTime": 1581435048,
                "Keys": {
                    "id": {
                        "S": "0001"
                    }
                },
                "OldImage": {
                    "name": {
                        "S": "クラスメソッド"
                    },
                    "id": {
                        "S": "0001"
                    }
                },
                "SequenceNumber": "321700000000000749702459",
                "SizeBytes": 37,
                "StreamViewType": "OLD_IMAGE"
            },
            "eventSourceARN": "arn:aws:dynamodb:ap-northeast-1:123456789012:table/demo-table/stream/2020-02-11T15:20:25.062"
        }
    ]
}

既存アイテムの既存属性の値を変更(MODIFY

  • 変更前のアイテム
{
  "id": "0001",
  "name": "クラスメソッド",
  "NumberOfOffice": "12"
}
  • 変更後のアイテム
{
  "id": "0001",
  "name": "クラスメソッド",
  "NumberOfOffice": "13"
}
  • DynamoDB StreamからLambdaに渡されたeventデータ
{
    "Records": [
        {
            "eventID": "f946f25ce5815d9a48a55971bfaf77d4",
            "eventName": "MODIFY",
            "eventVersion": "1.1",
            "eventSource": "aws:dynamodb",
            "awsRegion": "ap-northeast-1",
            "dynamodb": {
                "ApproximateCreationDateTime": 1581435116,
                "Keys": {
                    "id": {
                        "S": "0001"
                    }
                },
                "OldImage": {
                    "NumberOfOffice": {
                        "S": "12"
                    },
                    "name": {
                        "S": "クラスメソッド"
                    },
                    "id": {
                        "S": "0001"
                    }
                },
                "SequenceNumber": "321800000000000749723604",
                "SizeBytes": 53,
                "StreamViewType": "OLD_IMAGE"
            },
            "eventSourceARN": "arn:aws:dynamodb:ap-northeast-1:123456789012:table/demo-table/stream/2020-02-11T15:20:25.062"
        }
    ]
}

既存アイテムを削除(REMOVE

  • 削除前のアイテム
{
  "id": "0001",
  "name": "クラスメソッド",
  "NumberOfOffice": "13"
}
  • DynamoDB StreamからLambdaに渡されたeventデータ
{
    "Records": [
        {
            "eventID": "55cf616afb657b9687059615b99617a7",
            "eventName": "REMOVE",
            "eventVersion": "1.1",
            "eventSource": "aws:dynamodb",
            "awsRegion": "ap-northeast-1",
            "dynamodb": {
                "ApproximateCreationDateTime": 1581435230,
                "Keys": {
                    "id": {
                        "S": "0001"
                    }
                },
                "OldImage": {
                    "NumberOfOffice": {
                        "S": "13"
                    },
                    "name": {
                        "S": "クラスメソッド"
                    },
                    "id": {
                        "S": "0001"
                    }
                },
                "SequenceNumber": "321900000000000749748320",
                "SizeBytes": 53,
                "StreamViewType": "OLD_IMAGE"
            },
            "eventSourceARN": "arn:aws:dynamodb:ap-northeast-1:123456789012:table/demo-table/stream/2020-02-11T15:20:25.062"
        }
    ]
}

4. 新旧イメージ - 項目の新しいイメージと古いイメージの両方。(NEW_AND_OLD_IMAGES)

アイテム新規作成(INSERT

  • 新規作成したアイテム
{
  "id": "0001",
  "name": "クラスメソッド"
}
  • DynamoDB StreamからLambdaに渡されたeventデータ
{
    "Records": [
        {
            "eventID": "5fd7cb31037e429a3f69ea3b37b11643",
            "eventName": "INSERT",
            "eventVersion": "1.1",
            "eventSource": "aws:dynamodb",
            "awsRegion": "ap-northeast-1",
            "dynamodb": {
                "ApproximateCreationDateTime": 1581435982,
                "Keys": {
                    "id": {
                        "S": "0001"
                    }
                },
                "NewImage": {
                    "name": {
                        "S": "クラスメソッド"
                    },
                    "id": {
                        "S": "0001"
                    }
                },
                "SequenceNumber": "393300000000006058408605",
                "SizeBytes": 37,
                "StreamViewType": "NEW_AND_OLD_IMAGES"
            },
            "eventSourceARN": "arn:aws:dynamodb:ap-northeast-1:123456789012:table/demo-table/stream/2020-02-11T15:41:54.172"
        }
    ]
}

既存アイテムに属性追加(MODIFY

  • 変更前のアイテム
{
  "id": "0001",
  "name": "クラスメソッド"
}
  • 変更後のアイテム
{
  "id": "0001",
  "name": "クラスメソッド",
  "NumberOfOffice": "12"
}
  • DynamoDB StreamからLambdaに渡されたeventデータ
{
    "Records": [
        {
            "eventID": "54ef049ee8d1004af47015946580d481",
            "eventName": "MODIFY",
            "eventVersion": "1.1",
            "eventSource": "aws:dynamodb",
            "awsRegion": "ap-northeast-1",
            "dynamodb": {
                "ApproximateCreationDateTime": 1581436087,
                "Keys": {
                    "id": {
                        "S": "0001"
                    }
                },
                "NewImage": {
                    "NumberOfOffice": {
                        "S": "12"
                    },
                    "name": {
                        "S": "クラスメソッド"
                    },
                    "id": {
                        "S": "0001"
                    }
                },
                "OldImage": {
                    "name": {
                        "S": "クラスメソッド"
                    },
                    "id": {
                        "S": "0001"
                    }
                },
                "SequenceNumber": "393400000000006058444166",
                "SizeBytes": 84,
                "StreamViewType": "NEW_AND_OLD_IMAGES"
            },
            "eventSourceARN": "arn:aws:dynamodb:ap-northeast-1:123456789012:table/demo-table/stream/2020-02-11T15:41:54.172"
        }
    ]
}

既存アイテムの既存属性の値を変更(MODIFY

  • 変更前のアイテム
{
  "id": "0001",
  "name": "クラスメソッド",
  "NumberOfOffice": "12"
}
  • 変更後のアイテム
{
  "id": "0001",
  "name": "クラスメソッド",
  "NumberOfOffice": "13"
}
  • DynamoDB StreamからLambdaに渡されたeventデータ
{
    "Records": [
        {
            "eventID": "f3e083beba9cde0c1c9f05d2fe17b3f9",
            "eventName": "MODIFY",
            "eventVersion": "1.1",
            "eventSource": "aws:dynamodb",
            "awsRegion": "ap-northeast-1",
            "dynamodb": {
                "ApproximateCreationDateTime": 1581436133,
                "Keys": {
                    "id": {
                        "S": "0001"
                    }
                },
                "NewImage": {
                    "NumberOfOffice": {
                        "S": "13"
                    },
                    "name": {
                        "S": "クラスメソッド"
                    },
                    "id": {
                        "S": "0001"
                    }
                },
                "OldImage": {
                    "NumberOfOffice": {
                        "S": "12"
                    },
                    "name": {
                        "S": "クラスメソッド"
                    },
                    "id": {
                        "S": "0001"
                    }
                },
                "SequenceNumber": "393500000000006058457624",
                "SizeBytes": 100,
                "StreamViewType": "NEW_AND_OLD_IMAGES"
            },
            "eventSourceARN": "arn:aws:dynamodb:ap-northeast-1:123456789012:table/demo-table/stream/2020-02-11T15:41:54.172"
        }
    ]
}

既存アイテムを削除(REMOVE

  • 削除前のアイテム
{
  "id": "0001",
  "name": "クラスメソッド",
  "NumberOfOffice": "13"
}
  • DynamoDB StreamからLambdaに渡されたeventデータ
{
    "Records": [
        {
            "eventID": "8cce7a49515e7151c09f2a4dbefb285c",
            "eventName": "REMOVE",
            "eventVersion": "1.1",
            "eventSource": "aws:dynamodb",
            "awsRegion": "ap-northeast-1",
            "dynamodb": {
                "ApproximateCreationDateTime": 1581436190,
                "Keys": {
                    "id": {
                        "S": "0001"
                    }
                },
                "OldImage": {
                    "NumberOfOffice": {
                        "S": "13"
                    },
                    "name": {
                        "S": "クラスメソッド"
                    },
                    "id": {
                        "S": "0001"
                    }
                },
                "SequenceNumber": "393600000000006058474680",
                "SizeBytes": 53,
                "StreamViewType": "NEW_AND_OLD_IMAGES"
            },
            "eventSourceARN": "arn:aws:dynamodb:ap-northeast-1:123456789012:table/demo-table/stream/2020-02-11T15:41:54.172"
        }
    ]
}

まとめ

ここまでの調査によって、StreamViewTypeの違いによってJSON構造は変わらず、JSON内の同じ階層にNewImageOldImageのいずれかまたは両方が含まれるかどうかの違いがあることが分かりました。

また、StreamViewTypeおよびアイテム操作の種類によるNewImageOldImageの有無を表にまとめると以下のようになります。

項番 StreamViewType INSERT時 MODIFY時 DELETE時
1 KEYS_ONLY
2 NEW_IMAGE NewImage NewImage
3 OLD_IMAGE OldImage OldImage
4 NEW_AND_OLD_IMAGES NewImage NewImage
OldImage
OldImage

これら結果から、あるテーブルのDynamoDB StreamのStreamViewTypeを例えば「NEW_IMAGE」から「NEW_AND_OLD_IMAGES」に変更する場合に、すでにそのテーブルのDynamoDB Streamをトリガーにしている既存のLambdaのコード内でeventデータをevent['Records'][0]['dynamodb']['NewImage']のようにパースしていれば、既存のLambdaのコードに修正を加える必要はないということが分かりました。

おわりに

DynamoDB Streamのeventデータの内容の情報はAWS公式ドキュメントなどで見つけられなかったので、今後DynamoDB Streamを利用するたびに自分でも本記事を参照することになりそうです。

以上