Obter todos os itens do DynamoDB em Python (boto3)
Ler uma tabela inteira no boto3 significa paginar um scan até o fim. Cada resposta é limitada a 1 MB, e o paginator embutido do client de baixo nível segue o LastEvaluatedKey por todas as páginas para você (como funcionam os cursores do DynamoDB).
Qual API do boto3 você escolhe importa mais aqui do que a paginação, e o paginator é só metade do motivo.
Código
import boto3
client = boto3.client("dynamodb")
paginator = client.get_paginator("scan")
items = []
for page in paginator.paginate(TableName="Music"):
items.extend(page["Items"])
print(f"Table holds {len(items)} items")Explicação
- Paginators pertencem ao client, não ao resource —
boto3.resource("dynamodb").Table(…).scannão tem paginator nenhum, então lá você escreve o loop deLastEvaluatedKeyna mão. Só isso já é um bom motivo para usar o client de baixo nível em uma leitura completa. - A API de resource converte números para
Decimal— um{"N": "1994"}armazenado volta comoDecimal('1994'), que ojson.dumpsse recusa a serializar sem um encoder customizado. O client acima te entrega o{"N": "1994"}cru e deixa a conversão por sua conta (a codificação). - Ajuste o paginator em vez de substituí-lo —
paginator.paginate(TableName="Music", PaginationConfig={"PageSize": 500, "MaxItems": 10000}). O boto3 definePageSizecomo "o número de itens retornados por página de cada resultado" eMaxItemscomo um teto para o total, que emite umNextTokena partir do qual você retoma comStartingToken. - Scans paralelos precisam de um client por thread, construído com cuidado —
SegmenteTotalSegmentsdividem o trabalho, e a orientação do próprio boto3 é que clients são thread-safe enquanto sessions e resources não são. Ele também avisa que "Invokingboto3.client()inside of a concurrent context may result in response ordering issues". Construa o client antes de abrir o leque, ou dê a cada worker a sua própriaboto3.session.Session()(quando o paralelo vale a pena). itemscresce até o tamanho da tabela — trate cadapagedentro do loop em vez de estender uma lista que você mantém, a não ser que você já saiba que a tabela é pequena.- Um scan cobra cada byte que lê, em toda execução —
ProjectionExpressionencolhe a resposta e não a conta (por quê); umaFilterExpressiondescarta itens depois de eles serem lidos e cobrados (Scan com um filtro). Em um caminho quente você quer uma query.
Faça isso visualmente
A conta de um scan completo é o tamanho do item vezes a quantidade de itens, arredondado para cima em unidades de 4 KB. A calculadora de tamanho de item te dá a metade por item disso a partir de um item colado.
O DynoTable, em vez disso, pagina uma tabela ao vivo em uma grade com rolagem infinita, e o seu editor SQL nomeia a operação para a qual a sua consulta compila antes de você executá-la. A estimativa de RCU aparece somente quando os metadados da tabela permitem. Baixe o DynoTable.
Exemplos relacionados
- Obter todos os itens em Node.js — a mesma leitura completa com um loop explícito.
- Obter todos os itens com a AWS CLI — a CLI pagina por você.
- DynamoDB Scan em Python — scan com uma
FilterExpression. - Scans paralelos — Segment/TotalSegments, número de workers e quando vale o esforço.
- Por que meu Scan do DynamoDB é lento e caro? — o modelo de custo e como evitá-lo.
- DynamoDB ProvisionedThroughputExceededException — ler a tabela inteira é a forma clássica de esbarrar nele.
- "The provided starting key is invalid" — uma chave de retomada corrompida no loop de paginação.
Referências
- Scan — Amazon DynamoDB API Reference
- DynamoDB.Paginator.Scan — Boto3 documentation
- Scanning tables in DynamoDB — Amazon DynamoDB Developer Guide
- DynamoDB read and write operations (capacity unit consumption) — Amazon DynamoDB Developer Guide
- Paginators — Boto3 documentation
- Clients (thread safety) — Boto3 documentation
Verificado pela última vez em 2026-07-28 contra a documentação oficial da AWS vinculada acima.