Lambda(node.js)で、DynamoDBから超膨大なレコードを取得するプログラムを開発していました。
1分単位でクエリを実行して、レコードを小分け取得するようにしたのですが、
その際にプロパティを初期化できていなかったため、標題のエラーが発生したようです。
っていうことが、以下の記事を見てわかりました
https://qiita.com/nanananamememe/items/52293f1fece4458cc2fa
具体的な対策は delete params["ExclusiveStartKey"];
みたいな感じで
プロパティを消せば良いです。
すっごく長いですが、備忘録を兼ねてソースコードを掲載します
try{varENV=require('dotenv').config();varAWS=require('aws-sdk');AWS.config.update({region:process.env['AWS_DYNAMO_DB_REGION']});vardocClient=newAWS.DynamoDB.DocumentClient({apiVersion:'2012-08-10'});}catch(ex){console.error(ex);}varglobalSecondaryIndexes=[{key:'dummy',index:'dummy-created_at-index',}];varprimaryKeys={partitionKey:'log_id',sortKey:'created_at'};asyncfunctiongetBulk(runTime=null){varmyRunTime=runTime?runTime:newDate();varmyQuery="#partitionKey = :partitionVal AND #rangeKey BETWEEN :rangeStart and :rangeEnd";varparams={TableName:process.env['AWS_DYNAMO_DB_ACCESS_LOG_TABLE_NAME'],IndexName:globalSecondaryIndexes[0].index,ExpressionAttributeNames:{"#partitionKey":globalSecondaryIndexes[0].key,"#rangeKey":primaryKeys.sortKey},ExpressionAttributeValues:{":partitionVal":1,":rangeStart":0,":rangeEnd":0},KeyConditionExpression:myQuery};varresults=newObject();vardateRanges=[{"start":1586762880,"end":1586762939,},{"start":1586762940,"end":1586762999,}];try{for(variindateRanges){vardateRange=dateRanges[i];params["ExpressionAttributeValues"][":rangeStart"]=dateRange["start"];params["ExpressionAttributeValues"][":rangeEnd"]=dateRange["end"];deleteparams["ExclusiveStartKey"];// <-- ★★★★★★ これ!! ★★★★★★varresult=awaitget(params);// Array.objectresults[dateRange["start"]]=result;}returnresults;// Object.Array.object}catch(ex){console.error("Whoops, looks like something went wrong.");console.error(ex);thrownewError(ex);}};asyncfunctionget(params){try{// 初回のクエリ発行varresponse=awaitqueryGet(params);varresults=response.data;// Array.object// 二回目以降のクエリ発行while(response.LastEvaluatedKey){params.ExclusiveStartKey=response.LastEvaluatedKey;response=awaitqueryGet(params);// オブジェクトをマージArray.prototype.push.apply(results,response.data);}// オブジェクトを返すreturnresults;// Array.object}catch(ex){myFunc.logError("Whoops, looks like something went wrong.");myFunc.logError(ex);thrownewError(ex);}};functionqueryGet(parameter){returnnewPromise((resolve,reject)=>{docClient.query(parameter,(err,data)=>{if(err){console.error(err);reject(err);}else{if(data.LastEvaluatedKey){// 全件取得できていない場合、最後の取得位置を通知して再帰処理を行うresolve({data:data.Items,count:data.Count,LastEvaluatedKey:data.LastEvaluatedKey});}else{// 初回または最後の取得処理時resolve({data:data.Items,count:data.Count});}}});});};