Skip to content

DynamoDB

Single-table utilities (atlas.dynamodb) is the package that provides the foundational building blocks for implementing the Single-Table Design pattern on Amazon DynamoDB within Atlas-based applications.

It defines standardized abstractions for entity modeling and data access, enabling multiple domain entities to coexist safely and efficiently within a single DynamoDB table, while preserving strong consistency rules, clear ownership boundaries, and predictable access patterns.

The package is centered around these core concepts:

SingleTableEntity — base representation of a DynamoDB-backed domain entity

CanonicalEntity — independently addressable entity stored as <Entity>#<id> / META

AggregateEntity — child entity stored inside a stable parent partition

SingleTableConfig — declarative access-pattern configuration for unique constraints and collection indexes

SingleTableService — controlled access layer for reading and writing entities

Together, they enforce a clean separation between domain modeling and persistence mechanics, while remaining flexible enough to support complex access patterns, GSIs, and polymorphic records.

SingleTableService also supports DynamoDB transactional writes through transaction(). Writes called through compatible service instances inside the block automatically join the contextual transaction, so domain-service chains do not need to propagate a tx parameter. Nested blocks use REQUIRED propagation and only the root block commits. The returned transaction object remains available for explicit condition checks and advanced operations. Reads still observe only committed data; transactions do not provide read-your-own-writes. Use this API whenever one domain operation needs to create, replace, update, delete, or condition-check multiple items atomically. Transaction operations carry descriptions so Atlas can turn DynamoDB cancellation reasons into actionable ConflictError messages.

For higher-level entity persistence, prefer declarative access patterns through unique(), index(), and CompositeIndex. Atlas maintains the entity item, unique constraint items (UNIQUE#<Entity>#<field>#<value> / TARGET), collection index items (INDEX#<Entity>#<field>#<value> / <target address>), and aggregate identity lookup items in the same transaction through create(), replace(), and delete(). These methods also apply optimistic locking through an internal _version attribute. Low-level methods use the *_raw suffix when they intentionally bypass access-pattern maintenance and optimistic locking.

Composite-index queries support sort-key predicates through sort_begins_with, sort_between, sort_gte, sort_gt, sort_lte, and sort_lt. Raw queries expose the same DynamoDB key-condition shapes through the sk_* parameters.

Paged high-level queries expose opaque next_token values rather than raw DynamoDB LastEvaluatedKey objects. Index queries resolve target entities with DynamoDB batch reads to avoid one network round trip per access-pattern item. Public reads use DynamoDB's eventually consistent reads by default. Use strong_reads() for a consistency requirement that spans an operation, or pass consistent_read to override one call. Index collection queries omit unavailable targets and entities that no longer materialize the access-pattern item read by the query instead of returning stale matches or failing the complete collection read.

StorageAddress

Internal DynamoDB location for one persisted item.

Atlas application code should normally use entity ids instead of StorageAddress. The service computes this value when writing, reading, and maintaining access-pattern items.

AggregateConfig

Defines how an AggregateEntity is physically grouped and ordered.

parent identifies the owning entity type used in the aggregate partition key. parent_id is the field on the aggregate that contains the public id of that parent. sort lists the aggregate fields that compose the ordered portion of the DynamoDB sort key before the aggregate's own id.

SingleTableEntity

Bases: BaseModel

Base class for Atlas DynamoDB single-table domain entities.

The public identity of every entity is id. DynamoDB pk/sk values are storage-address details computed by Atlas and should not be used as domain foreign keys. Atlas persists _version as private optimistic-locking metadata; it is not a domain field.

Concrete application models normally inherit from CanonicalEntity or AggregateEntity rather than this class directly.

CanonicalEntity

Bases: SingleTableEntity

Standard single-table entity with independent identity.

A canonical entity is stored at <EntityName>#<id> / META. Use it for normal domain objects such as users, businesses, agents, contacts, templates, and integrations.

AggregateEntity

Bases: SingleTableEntity

Entity stored inside a stable parent partition.

Aggregate entities are meant for high-volume one-to-many collections whose main access pattern is listing children by parent with natural ordering, such as messages in a conversation or audit logs for an account.

SingleTableConfig

Declares access patterns that Atlas should maintain with an entity.

unique entries create unique constraint items. indexes entries create collection-style materialized index items suitable for query access. Explicit entries may refer to embedded model fields with dotted paths.

UniqueConstraint

Declares a unique constraint backed by an auxiliary constraint item.

The constraint is enforced by creating an auxiliary item whose key is derived from the entity type, field name, and field value. Creating this item with attribute_not_exists makes uniqueness safe under concurrency.

CollectionIndex

Declares a query-oriented materialized index backed by auxiliary items.

Multiple entities may share the same index partition key. Each indexed entity is differentiated by an index sort key that points back to the target entity's storage address.

CompositeIndex

Declares a collection index with composite partition and sort key parts.

Use this for access patterns such as "orders by customer ordered by created_at" or "agents by business grouped by role".

DynamoTransaction

Contextual builder for atomic DynamoDB write operations.

Use SingleTableService.transaction() to stage several entity operations, raw item operations, or condition checks that must succeed or fail together. Entity-level operations maintain declared access-pattern items in the same transaction. Nested transaction scopes join the active transaction and only the root scope commits.

DynamoQueryPage

Bases: Generic[T]

One page of DynamoDB query results.

items contains the typed entities or raw items returned by the query. next_token is an opaque pagination token that can be passed back to the matching page method. Atlas intentionally does not expose DynamoDB's raw LastEvaluatedKey as the public pagination contract.

SingleTableService

High-level persistence service for Atlas single-table DynamoDB entities.

The service stores both CanonicalEntity and AggregateEntity instances in the application's domain table, maintains materialized access-pattern items declared with unique(), index(), and CompositeIndex, and exposes reads by public id instead of by DynamoDB storage address.

create(entity, client_request_token=None)

Creates an entity and all declared access-pattern items atomically.

Aggregate entities also receive an internal id lookup item so get_by_id() can resolve them without requiring parent or sort fields.

delete(entity, client_request_token=None)

Deletes an entity and all access-pattern items Atlas can derive from it.

get_by_address(entity_cls, address, consistent_read=None)

Reads an entity by an explicit DynamoDB storage address.

Prefer get_by_id() in application code. This method is intended for infrastructure-level code that already has a StorageAddress. Reads inherit the contextual policy and are eventually consistent outside a policy block.

get_by_id(entity_cls, entity_id, consistent_read=None)

Reads an entity by its public id.

Canonical entities are addressed directly as <Entity>#<id> / META. Aggregate entities are resolved through Atlas' internal id lookup item. Reads inherit the contextual policy and are eventually consistent outside a policy block.

get_by_unique(entity_cls, field_or_name, value, consistent_read=None)

Reads one entity through a declared unique() access pattern.

Reads inherit the contextual policy and are eventually consistent outside a policy block. The method remains strict: an unavailable access-pattern item or target raises NotFoundError.

get_raw(pk, sk='META', consistent_read=None)

Reads one raw DynamoDB item by pk and sk.

This is a low-level method and does not hydrate an entity class. Reads inherit the contextual policy and are eventually consistent outside a policy block.

list_by_parent(entity_cls, parent_id, sort_begins_with=None, sort_between=None, sort_gte=None, sort_gt=None, sort_lte=None, sort_lt=None, consistent_read=None)

Lists aggregate children stored under one parent id.

This is the primary read path for AggregateEntity classes and queries the parent partition directly instead of going through an alternate access-pattern item.

list_by_parent_page(entity_cls, parent_id, limit=None, next_token=None, scan_forward=True, sort_begins_with=None, sort_between=None, sort_gte=None, sort_gt=None, sort_lte=None, sort_lt=None, consistent_read=None)

Paged version of list_by_parent().

query_by_index(entity_cls, field_or_name, value, sort_begins_with=None, sort_between=None, sort_gte=None, sort_gt=None, sort_lte=None, sort_lt=None, consistent_read=None)

Reads entities through a declared index() or CompositeIndex.

The method first queries materialized access-pattern items, then follows each item's target storage address. The caller does not need to know whether the target entity is canonical or aggregate. Targets unavailable during that second read are omitted from the collection.

query_by_index_page(entity_cls, field_or_name, value, limit=None, next_token=None, scan_forward=True, sort_begins_with=None, sort_between=None, sort_gte=None, sort_gt=None, sort_lte=None, sort_lt=None, consistent_read=None)

Paged version of query_by_index().

Pass the returned next_token to continue from the next page. A page can contain fewer resolved entities than limit when targets become unavailable between the access-pattern and entity reads.

replace(entity, client_request_token=None)

Replaces an entity while maintaining changed access-pattern items.

id is immutable. Aggregate parent_id and aggregate sort fields are also immutable because changing them would move the entity to another DynamoDB address.

strong_reads()

Temporarily makes DynamoDB reads strongly consistent.

The policy is isolated to the current execution context and applies across Atlas SingleTableService instances. Explicit consistent_read arguments override it. The previous policy is restored when the block exits, including when an exception is raised.

transaction(client_request_token=None)

Opens or joins a contextual DynamoDB write transaction.

Writes through compatible SingleTableService instances automatically join the active transaction. Nested scopes use REQUIRED propagation and only the root scope commits. Reads continue to observe committed data.