如何调整Lambda代码以将完整数据列表存入DynamoDB
问题解决:批量写入DynamoDB全量列表数据
你的代码逻辑上已经尝试遍历列表生成写入操作,但只存入第一个元素的问题,90%概率是DynamoDB主键冲突导致的覆盖,再加上单个Put请求并发执行可能触发限流,导致部分写入失败。下面是修正方案:
核心问题
如果你的DynamoDB表主键仅设置为userID(分区键)+MMYY(排序键),那么data里的所有条目都会写入同一个主键位置——后写入的条目会直接覆盖之前的,最终看起来像只保留了一条(你可能误判为仅存第一条)。另外,用Promise.all并发发起大量Put请求,容易触发DynamoDB的限流机制,导致部分写入失败。
修正后的完整代码
switch (event.routeKey) { case "PUT /sheets/{userID}/{MMYY}": console.log( "MYY", event.pathParameters.MMYY, "userID", event.pathParameters.userID, "Request Body", JSON.parse(event.body) ); // 安全解析请求体,确保data是数组 const requestBody = event.body ? JSON.parse(event.body) : {}; const data = Array.isArray(requestBody.data) ? requestBody.data : []; if (data.length === 0) { console.log("No data entries to save"); return { statusCode: 200, body: JSON.stringify({ message: "No valid data provided" }) }; } const MMYY = parseInt(event.pathParameters.MMYY); const userID = event.pathParameters.userID; // 转换为BatchWrite要求的PutRequest格式 const putRequests = data.map(item => ({ PutRequest: { Item: { userID, MMYY, dt: item.dt, bl: item.bl, bs: item.bs, ss: item.ss } } })); // 拆分批次(DynamoDB BatchWrite一次最多处理25条) const batchSize = 25; const batches = []; for (let i = 0; i < putRequests.length; i += batchSize) { batches.push(putRequests.slice(i, i + batchSize)); } // 分批执行批量写入 for (const batch of batches) { const batchCommand = new BatchWriteCommand({ RequestItems: { [tableName]: batch } }); await dynamo.send(batchCommand); } return { statusCode: 200, body: JSON.stringify({ message: "All data saved successfully", count: data.length }) }; }
关键调整说明
修复主键冲突:
必须修改DynamoDB表的主键设计,把dt加入主键组合(比如分区键userID,排序键用MMYY#${dt},或者将MMYY和dt设为复合排序键),确保每个data条目有唯一的主键标识,避免写入时覆盖。改用BatchWriteCommand:
替代原代码中单个PutCommand的并发执行,减少API调用次数,降低被DynamoDB限流的概率,这也是官方推荐的批量写入方式。数据合法性校验:
增加了data是否为数组的判断,避免因请求体格式错误导致的空写入。分批处理大列表:
因为DynamoDB的BatchWriteCommand一次最多支持25个条目,所以自动拆分超过25条的列表进行分批写入。
额外建议
- 可以添加错误捕获逻辑,处理
BatchWriteCommand返回的UnprocessedItems(如果有写入失败的条目,可进行重试)。 - 检查Lambda的执行超时时间,如果数据量较大,需要适当延长超时配置。
内容的提问来源于stack exchange,提问作者Honigeintopf
相关产品推荐
相关产品推荐

