boto3 icon indicating copy to clipboard operation
boto3 copied to clipboard

DynamoDB Table Resource should support Pagination for Scan and Query

Open rbu opened this issue 5 years ago • 12 comments

The boto3 "Table" Resource API does not provide easy access to paged results when using Scan or Query actions. That's unlike other high level boto3 Resource APIs like S3 which supports s3.Bucket('bucket').objects.pages().

The underlying DynamoDB client supports pagination, which leaves the boto3 user with the choice between nice attribute access + ugly pagination or ugly attribute access + nice pagination, which is unfortunate.

rbu avatar Jul 15 '19 08:07 rbu

@rbu - Thank you for your post. I will mark this as feature request.

swetashre avatar Jul 16 '19 20:07 swetashre

@rbu Thank you much for this, I'm also interested. I'm surprised by there being relatively little activity on this issue. But I suppose if the consumers of DynamoDB that aren't using some sort of ORM already are the main ones affected; I'm not really surprised. They're already dealing a lot with some gnarly JSON blobs.

tomislacker avatar Sep 22 '20 22:09 tomislacker

Any update on this feature request - is it planned at all?

kevindixon avatar Mar 16 '22 12:03 kevindixon

What is holding up this issue? Could I help?

systematicguy avatar Sep 27 '22 12:09 systematicguy

Thank you all for checking in and apologies for the delay.

We created a backlog item to look into this feature request and if anyone wants to share additional use cases or feedback then please feel free to leave a comment. Although we can't give a definite timeline at the moment, we'll make sure to keep it posted as soon as we have an update and please feel free to check back here in the future.

aBurmeseDev avatar Dec 15 '22 21:12 aBurmeseDev

I use a very simple implementation:

from typing import Callable, Dict, Iterator

def dynamodb_paginator(action: Callable, kwargs: Dict) -> Iterator[Dict]:
    while True:
        response = action(**kwargs)
        for item in response["Items"]:
            yield item
        if "LastEvaluatedKey" in response:
            kwargs["ExclusiveStartKey"] = response["LastEvaluatedKey"]
        else:
            break

Usage:

session = boto3.Session()
dynamodb = session.resource("dynamodb")
table = dynamodb.Table("my_table")
scan_kwargs = { "ScanFilter": ... }  # set here the arguments you would use in the scan() method call
for item in dynamodb_paginator(table.scan, scan_kwargs):
    ... # do something with the item

mrtj avatar Sep 06 '23 20:09 mrtj