首页 > 解决方案 > Dynamodb 扫描分页没有按我的预期工作

问题描述

Lambda 函数的 CloudWatch 日志

我正在使用下面的代码通过分页扫描 dynamodb 表,以从最多 20 条记录中提取 5 条记录。当我通过邮递员 GET 方法调用 api 时,它每次都提取相同的 5 条记录。这是否意味着我的 lambda 代码无法正常工作,或者我需要在邮递员中自定义我的 API 调用?

import boto3
import os
import json

def lambda_handler(event, context):

    client = boto3.client('dynamodb', region_name='ap-southeast-1')
    pagination_config={
            "MaxItems":20, 
            "PageSize": 5
            }
    
    paginator = client.get_paginator('scan')
    response_iterator = paginator.paginate(
        TableName="Users", 
        PaginationConfig=pagination_config
    )
    for page in response_iterator:
        Items = page['Items']
        print(Items)
        print("--------------------------")

    from botocore.paginate import TokenEncoder
    encoder = TokenEncoder()
    for page in response_iterator:
        if "LastEvaluatedKey" in page:
            encoded_token = encoder.encode({"ExclusiveStartKey": page["LastEvaluatedKey"]})
            pagination_config = {
                    "MaxItems": 20,
                    "PageSize": 5,
                    "StartingToken": encoded_token
                    }
            Items = page['Items']
            
    return {
        'statusCode': 200,
        'headers': {},
        'body': json.dumps(Items)
    }

标签: pythonaws-lambdapaginationamazon-dynamodbboto3

解决方案


分页时,您需要从LastEvaluatedKey上一次调用的开始。在发布的代码中LastEvaluatedKey,一遍又一遍地使用相同的代码,这将不允许分页并产生相同的结果。这是一个可以在本地运行的示例

import os
import json
from botocore.paginate import TokenEncoder

def lambda_handler(event, context):
    key= event['key'] 
    client = boto3.client('dynamodb', region_name='ap-southeast-1')
    
    if not key:
        pagination_config = {"MaxItems": 20, "PageSize": 5}
    else:
        encoder = TokenEncoder()
        encoded_token=encoder.encode({'ExclusiveStartKey':  {'id': {'S': key}}})
        pagination_config = {"MaxItems": 20, "PageSize": 5, "StartingToken":  encoded_token } 
        

    paginator = client.get_paginator('scan')
    response_iterator = paginator.paginate(
        TableName="Users", 
        PaginationConfig=pagination_config
    )
            
    for page in response_iterator:
        Items = page['Items']
    return {
        'statusCode': 200,
        'headers': {},
        'body': json.dumps(Items),
        'LastEvaluatedKey' : page["LastEvaluatedKey"]
    }

在响应中,最后评估的密钥将如下所示:

"LastEvaluatedKey": {"id": {"S": "???????"}}}"

请务必将其用于您的下一个分页。


推荐阅读