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

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

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

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

実際に調べてみた

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およびレコード操作の種類によるNewImageキーとOldImageキーの有無を表にまとめると以下のようになります。

項番 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を利用するたびに自分でも本記事を参照することになりそうです。

以上