DynamoDB DocumentClient使用scan方法实现分页失败如何解决?
问题根因
首次返回重复结果原因
- 初始组件未存储上一次请求返回的分页锚点
LastEvaluatedKey,每次调用getItems都无参数传入,相当于每次都从第一页开始查询,自然返回相同内容 getItems函数中ExclusiveStartKey的字段名写错:你的posts表主键是postId,但代码中手动写死了item_id,结构不匹配
后续ValidationException报错原因
你修改后getItems返回的是完整的LastEvaluatedKey对象(结构为{postId: "xxx"}),但函数内部还是将传入的lastItem作为单值拼接成{item_id: lastItem},最终传给DynamoDB的起始键结构完全不符合表主键定义,因此触发校验错误。
修复后代码
getItems函数
async function getItems(lastEvaluatedKey) { try { const params = { TableName: "posts", Limit: 1, }; // DynamoDB返回的LastEvaluatedKey可直接透传,无需手动拼接结构 if (lastEvaluatedKey) { params.ExclusiveStartKey = lastEvaluatedKey; } const response = await docClient.scan(params).promise(); return { items: response.Items, // 下一页的起始锚点,无值时代表已经到最后一页 nextStartKey: response.LastEvaluatedKey }; } catch (error) { throw error; } }
组件代码
import { useState, useEffect } from 'react'; import { getItems } from "../../atoms/functions/AWS"; function Test() { // 存储所有已加载的帖子列表 const [postList, setPostList] = useState([]); // 存储下一页查询的起始锚点 const [nextStartKey, setNextStartKey] = useState(null); // 首次进入加载第一页 useEffect(() => { fetchNextPage(); }, []); const fetchNextPage = async () => { const result = await getItems(nextStartKey); // 新数据追加到现有列表 setPostList(prev => [...prev, ...result.items]); // 更新下一页锚点 setNextStartKey(result.nextStartKey); }; return ( <div> {/* 渲染已加载的帖子 */} {postList.map(post => ( <div key={post.postId}>帖子ID:{post.postId}</div> ))} {/* 还有下一页时显示加载按钮 */} {nextStartKey && <button onClick={fetchNextPage}>加载下一页</button>} </div> ); }
注意事项
- DynamoDB返回的
LastEvaluatedKey是符合表主键结构的完整对象,不要拆解后自行拼接,直接作为下一次请求的ExclusiveStartKey传入即可 - 如果表有排序键,
LastEvaluatedKey会同时包含分区键和排序键,同样直接透传即可 - 当请求返回的结果中不存在
LastEvaluatedKey时,代表已经遍历完所有数据,无需再发起分页请求
内容的提问来源于stack exchange,提问作者mmz
相关产品推荐
相关产品推荐

