dynobase-icon
Dynobase

DynamoDB and Python: Boto3 Query and CRUD Cheat Sheet

Rafal Wilinski

Written by Rafal Wilinski

Last updated: October 23rd, 2026

Writing DynamoDB code by hand? Dynobase turns supported data operations into application code or scripts, and generates CDK, CloudFormation or Terraform for an existing table. Code generation in Dynobase

Boto3 is the AWS SDK for Python. For DynamoDB, its resource interface reads and writes Python dictionaries through Table objects, while its client interface exposes the service APIs using DynamoDB's typed attribute values. Use Key for query key conditions, Attr for filters and conditions, and pagination whenever a Query or Scan can span multiple responses.

What is boto3, and should you use a resource or client?

Both interfaces are part of boto3. The resource is convenient for established item operations, including automatic batch writing. AWS has frozen new feature development for resources; existing resource APIs continue to work, while newer features are available through clients.

InterfaceExampleValuesUse it for
Resourcedynamodb.Table("Movies").get_item(...)Native dictionaries, integers, Decimal, setsCommon item operations and batch_writer
Clientclient.get_item(...)Attribute values such as {"N": "2026"}Full service API, transactions and explicit paginators

Do not pass already serialized attributes into a resource operation: it will treat those descriptors as ordinary dictionaries. Conversely, a separately created client requires typed values. The examples below use distinct resource and client objects to keep that boundary clear.

Cheat-sheet contents

Connect boto3 to DynamoDB

Current boto3 requires Python 3.10 or later. Use a virtual environment and install boto3 there. For new Lambda examples, choose a supported runtime such as Python 3.13 and package the dependencies you need.

Run this setup once before the later Python snippets. They share the Movies table, with Number partition key year and String sort key title. A GenreIndex with String partition key genre and String sort key title supports the index example.

Use your AWS profile during local development, for example by setting AWS_PROFILE, or let a Lambda execution role provide credentials. Do not embed access keys in application code. Constructing Table("Movies") creates a local resource object; it does not create the remote table.

The boto3 DynamoDB guide documents the resource API. Equivalent examples are available for Node.js and Java.

Create a table

The key schema and attribute definitions must agree on names and types. Define only table and index keys, not every attribute you intend to store. This creates an on-demand table and waits for it to become active.

A client-based equivalent waits with client.get_waiter("table_exists").wait(TableName="Movies"). Waiter timeouts are failures to finish waiting, not proof that the table will never become active.

Delete a table

Call delete() on a table resource, or delete_table() on a client. The service resource itself has no delete_table method. This removes all table data and indexes, so run it only when finished with the disposable example table.

Deletion protection blocks this request when enabled. Item deletion, covered below, leaves the table and its configuration intact.

List tables

A client paginator retrieves all table names for the configured account and Region. A single list_tables() response may be incomplete.

The resource alternative, dynamodb.tables.all(), also handles pagination when iterated. Avoid turning it into a list unless you need all resource objects in memory.

Get all items with Scan

A Scan reads the table page by page. The helper below also accepts query, so later examples can reuse it without losing conditions, index names or filters on subsequent requests.

Filter with Attr for non-key attributes. Keep the filter on every page, including pages after an empty result:

DynamoDB evaluates up to 1 MB before filtering. Filters reduce returned data, not the read capacity spent evaluating it. Even a strongly consistent scan does not provide a table-wide snapshot. Use Query when the access pattern identifies a partition.

Get one item

Supply the full primary key with its correct types. The resource returns DynamoDB Numbers as Decimal, and an absent item is represented by a response without Item.

get_item does not query a secondary index. Use Query for index lookups, then read the base item when you need attributes not projected into that index.

Batch get items with retries

BatchGet accepts up to 100 keys and returns at most 16 MB. It may return partial results with UnprocessedKeys even when the request succeeds. Retry only those keys with backoff; results are unordered, and missing items are omitted.

Deduplicate input keys and split larger inputs into separate requests. Automatic SDK retries for failed requests do not replace this loop for successful responses containing unfinished work.

Put an item

put_item replaces the entire item at the same key. Add a condition to make it create-only. Attributes that are not keys can vary between items.

The condition is checked against the item identified by both key attributes. An existing movie with another title in the same year does not block the insert.

Batch write items

batch_writer() buffers puts and deletes, splits them into batches, and resends unprocessed items. Exiting the context flushes remaining work. It does not provide transactions, conditions or partial attribute updates.

overwrite_by_pkeys deduplicates matching keys in the local buffer; it is not a server-side conditional write. Each put still replaces the full stored item. For jobs needing a strict deadline, checkpointing or custom backoff, implement a bounded client batch_write_item loop and retain UnprocessedItems. The batch writer reference describes the helper's behavior.

Query a set of items

Use Key for the partition-key equality and an optional sort-key predicate. Query can read a base table or an index; it does not require a secondary index. Use the read_pages helper from the Scan section to retrieve every page.

The key condition narrows what DynamoDB reads. The filter runs afterward and must not replace the required partition-key condition. See query examples for other access patterns.

Query an index

This uses the GenreIndex defined above. Its partition key is genre, so the key condition must use genre, not the base table's year.

Global secondary indexes allow only eventually consistent reads. Setting ConsistentRead=True on a GSI query fails. The example index projects all attributes; narrower projections return fewer attributes.

Update selected attributes

Use an expression to change attributes without replacing the whole item. Alias attribute names to avoid reserved-word conflicts. The existence condition prevents UpdateItem from creating an item when the key is absent.

You cannot change primary-key attributes with UpdateItem. Moving an item to another key requires writing a new item and deleting the old one, optionally in a transaction.

Conditionally update an item

A condition and update execute atomically. This changes the rating only if it still equals the expected value, so a concurrent writer cannot silently overwrite another change.

A false condition raises ClientError with code ConditionalCheckFailedException. Treat that as an application conflict, not a transient error to retry indefinitely.

Increment an attribute atomically

ADD increments a top-level Number without a read-modify-write race. A missing numeric attribute starts at zero. The condition below requires the movie itself to exist.

An atomic increment is not idempotent: retrying after an ambiguous timeout can increment twice. For nested counters, use SET #stats.#views = if_not_exists(#stats.#views, :zero) + :one with name aliases and values, and ensure the parent stats map already exists.

Delete one item

Delete with the full primary key. Without a condition, a missing item is a successful no-op. ALL_OLD returns the removed item when present.

Use a condition when deletion must depend on a rating, status or version that another writer could change.

Delete all items without deleting the table

Scan both key attributes and delete through the batch writer. This is destructive and is not an atomic truncate. Stop concurrent writers and take an appropriate backup before clearing a table; concurrent inserts can survive the scan, and concurrent replacements can be deleted.

Projection reduces response size, not read capacity. Keep writers stopped while verifying the table is empty. The delete-all-items guide covers alternatives and operational trade-offs.

Query with sorting

Query orders results by the sort key within the selected partition. ScanIndexForward=False reverses the order. It does not sort by an arbitrary attribute such as rating, and Scan has no equivalent ordering option.

Here the sort key is a String, so titles follow UTF-8 byte order. To sort by another attribute efficiently, design an index with that attribute as its sort key.

Query and scan with client paginators

Resource loops use LastEvaluatedKey as the next request's ExclusiveStartKey, as read_pages does. Clients also offer paginators. The separately created client below uses typed values and returns typed items, so deserialize each attribute.

PageSize controls the number of evaluated items per request, not the number of filtered matches. MaxItems limits the paginator's total results and can stop early. Follow continuation state even when a page contains no matches. See the Query paginator reference.

Decimal values and DynamoDB JSON

The resource serializer accepts integers and Decimal, but rejects Python float. Construct decimals from strings to avoid carrying binary floating-point errors into the value. Parse JSON numbers directly as Decimal when importing data.

This JSON encoder deliberately emits decimals as strings to preserve precision. Choose a different explicit representation if your API contract requires numeric JSON; converting everything to float can lose information. Sets and binary values also need their own JSON representation. The boto3 type conversion source lists supported conversions.

Write and read transactions through the client

A write transaction applies all operations or none. Use the client with typed attributes; the resource interface has no transaction method. This example creates two different movie items with create-only conditions.

Use a distinct token for each logical write, retaining that token and identical parameters across retries. Its idempotency window is 10 minutes. Transactions allow up to 100 unique items and 4 MB within one account and Region. You cannot target the same item twice, and MRSC global tables do not support transactions. See the transaction API.

Read the pair atomically using transact_get_items; results follow the requested order and contain typed attributes:

Handle errors by ClientError code

Catch ClientError for service errors and inspect response["Error"]["Code"]. Do not parse message text or silently turn every exception into an empty result.

TransactionCanceledException requires examining the transaction's failure, not treating it as a successful write. Credential errors and local parameter validation errors are botocore exceptions outside ClientError. SDK retries handle some transient failures; they do not fix invalid keys or failed conditions. The error handling reference explains the distinction.

Use boto3 with DynamoDB Local

Start DynamoDB Local with Docker, then override the endpoint on both interfaces. These dummy credentials are only for the local endpoint.

Create the table against this endpoint before running item operations. This in-memory container loses data when stopped and cannot reproduce every cloud behavior. See running DynamoDB locally for persistent storage and environment setup.

Frequently asked questions

Frequently Asked Questions

What is boto3 in Python?

Boto3 is the AWS SDK for Python. It provides clients and resource objects for DynamoDB and other AWS services, with credential discovery, request signing and retry support.

Should I use a boto3 DynamoDB resource or client?

A resource Table object is convenient for common operations using native Python values and batch_writer. Use the client for the complete service API and transactions; AWS does not add new features to the resources interface.

How do I scan all DynamoDB items with Python?

Keep calling Scan with the previous response's LastEvaluatedKey as ExclusiveStartKey until the key is absent, or use a client paginator. Preserve filters on every request, and keep going after empty filtered pages.

Why does boto3 reject float values for DynamoDB?

The DynamoDB resource serializer accepts integers and Decimal values rather than Python float. Use Decimal constructed from a string, or json.loads with parse_float=Decimal, to preserve decimal precision.

Can I use Python and DynamoDB without hardcoded access keys?

Yes. Boto3 can use AWS profiles for local development and IAM role credentials in AWS runtimes. Keep credentials out of source code and grant only the operations your application needs.

Dynobase is a Professional GUI Client for DynamoDB

Start your 7-day free trial today

Product Features

Download
/
Changelog
/
Pricing
/
Member Portal
/
Privacy
/
EULA
/
Twitter
© 2026 Dynobase