この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは、CX事業本部 IoT事業部の若槻です。
今回は、Amazon DynamoDBでの各種データ更新操作(putItem、updateItem)による変更データキャプチャのストリームデータの内容を確認してみました。
DynamoDBのストリームデータって更新時はどうなるんだっけ?
Amazon DynamoDBでは、各データ操作時の変更データをキャプチャする設定して、そのキャプチャデータをストリームとして別の機能に連携することができます。
ストリームから得られるデータは次のような構成になります。NewImage
とOldImage
に新旧のデータが格納される形になります。
{
"eventID":"2",
"eventName":"MODIFY",
"eventVersion":"1.0",
"eventSource":"aws:dynamodb",
"awsRegion":"us-east-1",
"dynamodb":{
"Keys":{
"Id":{
"N":"101"
}
},
"NewImage":{
"Message":{
"S":"This item has changed"
},
"Id":{
"N":"101"
}
},
"OldImage":{
"Message":{
"S":"New item!"
},
"Id":{
"N":"101"
}
},
"SequenceNumber":"222",
"SizeBytes":59,
"StreamViewType":"NEW_AND_OLD_IMAGES"
},
"eventSourceARN":"stream-ARN"
}
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/with-ddb.html
最近このDynamoDBの変更データキャプチャを使用した実装を行うことがあったのですが、その際にキャプチャデータの構成はPutItem
やUpdateItem
などの操作によって違いがあるのか?というのが気になったので確認してみました。
確認してみた
次の構成を作成して、各種操作を行ってみます。
次のスクリプトを実行してPutItemとUpdateItemのデータ更新操作を実行してみます。
行っている更新操作は次の5パターンです。
- PutItem
- 新規作成
- プロパティ値変更
- プロパティ削除
- プロパティ追加
- UpdateItem
- 一部プロパティ値変更
import * as AWS from 'aws-sdk';
const dynamodb = new AWS.DynamoDB({ region: 'ap-northeast-1' });
it('データ更新操作', async () => {
const deviceId = 'd001';
//PutItem(新規作成)
await dynamodb
.putItem({
Item: {
deviceId: {
S: deviceId,
},
deviceName: {
S: 'デバイス001',
},
position: {
S: 'A-25',
},
},
TableName: 'devicesTable',
})
.promise();
//PutItem(プロパティ値変更)
await dynamodb
.putItem({
Item: {
deviceId: {
S: deviceId,
},
deviceName: {
S: 'デバイス001',
},
position: {
S: 'B-20',
},
},
TableName: 'devicesTable',
})
.promise();
//PutItem(プロパティ削除)
await dynamodb
.putItem({
Item: {
deviceId: {
S: deviceId,
},
deviceName: {
S: 'デバイス001',
},
},
TableName: 'devicesTable',
})
.promise();
//PutItem(プロパティ追加)
await dynamodb
.putItem({
Item: {
deviceId: {
S: deviceId,
},
deviceName: {
S: 'デバイス001',
},
position: {
S: 'C-05',
},
},
TableName: 'devicesTable',
})
.promise();
//UpdateItem(一部プロパティ値変更)
await dynamodb
.updateItem({
Key: {
deviceId: {
S: deviceId,
},
},
ExpressionAttributeValues: {
':deviceName': {
S: 'デバイス0000001',
},
},
ExpressionAttributeNames: {
'#deviceName': 'deviceName',
},
UpdateExpression: 'set #deviceName = :deviceName',
TableName: 'devicesTable',
})
.promise();
});
操作を行ってから少しするとS3バケット内にオブジェクトが生成されました。
このオブジェクトに対してS3 Selectをすると次のような結果を得られました。
//PutItem(新規作成)
// 新規作成なのでNewImageでのみデータのすべてのプロパティが記録されている
{
"awsRegion": "ap-northeast-1",
"eventID": "e949e41e-d088-4ffb-855f-c7bff2fa79b6",
"eventName": "INSERT",
"userIdentity": null,
"recordFormat": "application/json",
"tableName": "devicesTable",
"dynamodb": {
"ApproximateCreationDateTime": 1640184077807,
"Keys": {
"deviceId": {
"S": "d001"
}
},
"NewImage": {
"deviceName": {
"S": "デバイス001"
},
"deviceId": {
"S": "d001"
},
"position": {
"S": "A-25"
}
},
"SizeBytes": 61
},
"eventSource": "aws:dynamodb"
}
//PutItem(プロパティ値変更)
// OldImageで変更前、NewImageで変更後のデータのすべてのプロパティが記録されている
{
"awsRegion": "ap-northeast-1",
"eventID": "3e908ea4-6b4f-40b4-a098-1c8b0172fde8",
"eventName": "MODIFY",
"userIdentity": null,
"recordFormat": "application/json",
"tableName": "devicesTable",
"dynamodb": {
"ApproximateCreationDateTime": 1640184109255,
"Keys": {
"deviceId": {
"S": "d001"
}
},
"NewImage": {
"position": {
"S": "B-20"
},
"deviceName": {
"S": "デバイス001"
},
"deviceId": {
"S": "d001"
}
},
"OldImage": {
"position": {
"S": "A-25"
},
"deviceName": {
"S": "デバイス001"
},
"deviceId": {
"S": "d001"
}
},
"SizeBytes": 110
},
"eventSource": "aws:dynamodb"
}
//PutItem(プロパティ削除)
// OldImageでのみ削除前のプロパティが記録されている
{
"awsRegion": "ap-northeast-1",
"eventID": "7c7c1f3d-93b0-45b7-9bb9-ec778822fb51",
"eventName": "MODIFY",
"userIdentity": null,
"recordFormat": "application/json",
"tableName": "devicesTable",
"dynamodb": {
"ApproximateCreationDateTime": 1640184109318,
"Keys": {
"deviceId": {
"S": "d001"
}
},
"NewImage": {
"deviceName": {
"S": "デバイス001"
},
"deviceId": {
"S": "d001"
}
},
"OldImage": {
"position": {
"S": "B-20"
},
"deviceName": {
"S": "デバイス001"
},
"deviceId": {
"S": "d001"
}
},
"SizeBytes": 98
},
"eventSource": "aws:dynamodb"
}
//PutItem(プロパティ追加)
// NewImageでのみ追加したプロパティが記録されている
{
"awsRegion": "ap-northeast-1",
"eventID": "36f03059-96eb-4a86-8717-25697c7d77ce",
"eventName": "MODIFY",
"userIdentity": null,
"recordFormat": "application/json",
"tableName": "devicesTable",
"dynamodb": {
"ApproximateCreationDateTime": 1640184109371,
"Keys": {
"deviceId": {
"S": "d001"
}
},
"NewImage": {
"position": {
"S": "C-05"
},
"deviceName": {
"S": "デバイス001"
},
"deviceId": {
"S": "d001"
}
},
"OldImage": {
"deviceName": {
"S": "デバイス001"
},
"deviceId": {
"S": "d001"
}
},
"SizeBytes": 98
},
"eventSource": "aws:dynamodb"
}
//UpdateItem(一部プロパティ値変更)
// update対象であるかに関わらず、すべてのプロパティの変更前後の値が記録されている
{
"awsRegion": "ap-northeast-1",
"eventID": "e475ba62-78fb-4e4d-9a9f-a8f3748013a3",
"eventName": "MODIFY",
"userIdentity": null,
"recordFormat": "application/json",
"tableName": "devicesTable",
"dynamodb": {
"ApproximateCreationDateTime": 1640184109433,
"Keys": {
"deviceId": {
"S": "d001"
}
},
"NewImage": {
"position": {
"S": "C-05"
},
"deviceName": {
"S": "デバイス0000001"
},
"deviceId": {
"S": "d001"
}
},
"OldImage": {
"position": {
"S": "C-05"
},
"deviceName": {
"S": "デバイス001"
},
"deviceId": {
"S": "d001"
}
},
"SizeBytes": 114
},
"eventSource": "aws:dynamodb"
}
結論として、どのような変更操作であるかに関わらず、操作前後のデータのすべてのプロパティがNewImageとOldImageに記録されるということが確認できました!
参考
以上