Pagination DynamoDB通过Boto3分页,NextToken不存在,但LastEvaluatedKey是否存在?

Pagination DynamoDB通过Boto3分页,NextToken不存在,但LastEvaluatedKey是否存在?,pagination,amazon-dynamodb,boto3,Pagination,Amazon Dynamodb,Boto3,boto3和dynamodb分页器的文档指定在分页时应返回NextToken,然后在下一个StartingToken查询中包含该令牌以恢复分页会话(通过RESTful API访问信息时会发生这种情况) 但是,我的测试表明,它不会在结果中返回NextToken,而是返回LastEvaluatedKey。我想我可以使用LastEvaluatedKey作为令牌,但这不起作用 paginator = client.get_paginator('scan') page_iterator = paginat

boto3和dynamodb分页器的文档指定在分页时应返回NextToken,然后在下一个StartingToken查询中包含该令牌以恢复分页会话(通过RESTful API访问信息时会发生这种情况)

但是,我的测试表明,它不会在结果中返回NextToken,而是返回LastEvaluatedKey。我想我可以使用LastEvaluatedKey作为令牌,但这不起作用

paginator = client.get_paginator('scan')
page_iterator = paginator.paginate(TableName='test1', PaginationConfig={'PageSize': 1 , 'MaxItems': 5000,  'MaxSize': 1 })

    for page in page_iterator:
        print(page)
        break   
我希望从page_迭代器返回的page对象包含NextToken键,但它没有

{'Items': [{'PK': {'S': '99'}, 'SK': {'S': '99'}, 'data': {'S': 'Test Item 99'}}], 'Count': 1, 'ScannedCount': 1, 'LastEvaluatedKey': {'PK': {'S': '99'}, 'SK': {'S': '99'}}, 'ResponseMetadata': {'RequestId': 'DUE559L8KVKVH8H7G0G2JH0LUNVV4KQNSO5AEMVJF66Q9ASUAAJG', 'HTTPStatusCode': 200, 'HTTPHeaders': {'server': 'Server', 'date': 'Mon, 27 May 2019 14:22:09 GMT', 'content-type': 'application/x-amz-json-1.0', 'content-length': '153', 'connection': 'keep-alive', 'x-amzn-requestid': 'DUE559L8KVKVH8H7G0G2JH0LUNVV4KQNSO5AEMVJF66Q9ASUAAJG', 'x-amz-crc32': '3759060959'}, 'RetryAttempts': 0}}
我错过了什么


更新:与此相关吗

有几种方法可以使用boto3扫描分页器解决此问题

第一个选项是调用
build\u full\u result
,如下所示:

result = paginator.paginate(TableName="your_table", PaginationConfig={"MaxItems":10, "PageSize": 10}).build_full_result()
返回包含10项的响应,如果有10项以上,则填充“NextToken”。这可能是最简单的方法,您可以将MaxItems视为返回的页面大小,如果“NextToken”为空,则扫描结束

我注意到,如果不指定页面大小,结果是相同的,但消耗的容量和“ScannedCount”更高

另一种方法是直接使用中的TokenEncoder对“StartingToken”进行编码

如果对分页器的初始调用类似于:

pagination_config = {
    "MaxItems": 5000,
    "PageSize": 10,
}

scan_iterator = scan_paginator.paginate(
    TableName="your_table_name",
    PaginationConfig=pagination_config
)
分页结果将如问题所述。前10个结果将在第一页中返回,未指定“NextToken”,但指定了“LastEvaluatedKey”

要使用它,请将返回的“LastEvaluatedKey”编码为“ExclusiveStartKey”,并将其作为分页配置中的“StartingToken”传入

from botocore.paginate import TokenEncoder
encoder = TokenEncoder()
for page in scan_iterator:
    if "LastEvaluatedKey" in page:
            encoded_token = encoder.encode({"ExclusiveStartKey": page["LastEvaluatedKey"]})
然后:


将主键编码为“ExclusiveStartKey”的原因是它正是用户所期望的。本质上,分页器将“LastEvaluatedKey”和“ExclusiveStartKey”编码/解码为“NextToken”和“StartingToken”值。如果您对生成完整结果时返回的“NextToken”进行base64解码,您将看到它也使用了“ExclusiveStartKey”。

在获取页面迭代器对页面进行迭代时,为什么需要令牌?因为我将此页面数据返回到HTTP API客户端。我还需要归还该代币,以便他们可以在后续请求中返回并获得下一页。谢谢。我最终没有使用分页API,只是获取了对其进行编码的LastEvaluatedKey base64,然后允许在后续调用中传回它。因此,虽然我不是真的对它进行分页,但我认为它将允许更有效的使用,并且浪费的读取次数将更低。
pagination_config = {
    "MaxItems": 500,
    "PageSize": 10,
    "StartingToken": encoded_token
}