A developer-friendly library for DynamoDB that simplifies single-table design without ORM lock-in
Project description
Dynamixe
A developer-friendly library for DynamoDB that simplifies single-table design without ORM lock-in.
Features
- Expression-based API - SQLAlchemy-style attribute access for type-safe queries
- Model configuration - Pydantic-compatible
model_configpattern - No ORM lock-in - Works with Pydantic, dataclasses, or plain dicts
- Transactional operations - Full support for transact_get and transact_write
- Conditional operations - Expression-based conditions with custom exceptions
- JMESPath transformations - Transform transactional results with powerful queries
Installation
pip install dynamixe
Quick Start
Define a Model
from dynamixe import Model, ConfigDict
class User(Model):
model_config = ConfigDict(
table='users',
partition_key='id',
sort_key='sk',
)
id: str
sk: str
name: str
Use Expressions
# SQLAlchemy-style expression access
User.id == 'USER#10' # Equality
User.sk.not_exists() # Condition
User.name.begins_with('A') # Begins with
User.sk.between('0', '100') # Range
# Combine expressions
(User.id == 'USER#10') & (User.sk == '0')
Conditional Put
from dynamixe import DynamoDBClient
client = DynamoDBClient(table_name='users')
# Put with condition using expressions
client.put_item(
user,
cond_expr=User.sk.not_exists(),
)
Query Items
# Query with key condition expression
result = client.query(
User.id == 'USER#10',
scan_index_forward=True,
limit=10,
)
# Access results as dict
items = result['items']
count = result['count']
last_key = result['last_key'] # For pagination
# Transform with JMESPath
names = result.jmespath('[*].name')
# ['Alice', 'Bob', 'Charlie']
Transactional Writes
from dynamixe import TransactWriter, TransactionOperationFailed
class EmailConflictError(TransactionOperationFailed):
pass
with TransactWriter('users', client=boto3_client) as tx:
tx.put(
item={'id': 'USER#1', 'sk': '0', 'name': 'Alice'},
cond_expr=User.sk.not_exists(),
exc_cls=EmailConflictError,
)
# Or via client
with client.transact_writer() as tx:
...
Transactional Reads
from dynamixe import TransactGet, get
tx = TransactGet('users', client=boto3_client)
result = tx.get_items(
get({'id': 'USER#1', 'sk': '0'}),
get({'id': 'USER#2', 'sk': '0'}).project(User.name, User.email),
)
# Or via client
tx = client.transact_get()
result = tx.get_items(...)
JMESPath Transformations
Transform transactional results with JMESPath expressions:
from dynamixe import TransactGet, get
tx = client.transact_get()
names = tx.get_items(
get({'id': 'USER#1', 'sk': '0'}),
get({'id': 'USER#2', 'sk': '0'}),
).jmespath('[*].name')
# ['Alice', 'Bob']
The TransactGetResult wrapper supports list-like operations:
result = tx.get_items(get({'id': 'USER#1', 'sk': '0'}))
len(result) # 1
result[0] # {'id': 'USER#1', ...}
for item in results:
print(item['name'])
Works with Any Model Pattern
Pydantic:
from pydantic import BaseModel
class User(BaseModel):
model_config = ConfigDict(table='users', partition_key='id')
id: str
name: str
Dataclass (via __dynamodb_config__):
from dataclasses import dataclass
@dataclass
class User(Model):
__dynamodb_config__ = ConfigDict(
table='users',
partition_key='id',
sort_key='sk',
)
id: str
sk: str
name: str
Plain dict:
# No model needed
client.put_item({'id': 'USER#1', 'sk': '0', 'name': 'Alice'})
API Reference
DynamoDBClient
get_item(key, ...)- Get single itemput_item(item, cond_expr=..., exc_cls=...)- Put with conditionupdate_item(key, update_expr, ...)- Update itemdelete_item(key, cond_expr=...)- Delete itemquery(key_expr, ...)- Query items by key conditionscan(filter_expr=...)- Scan all items with optional filtertransact_get()- Start transactional readtransact_writer(flush_amount=50)- Start transactional write
Model
model_config- Class attribute for DynamoDB configurationget_table()- Get table nameget_partition_key()- Get partition key attributeget_sort_key()- Get sort key attribute
ConfigDict
ConfigDict(
table='table-name',
partition_key='pk',
sort_key='sk', # optional
)
Expressions
- Comparison:
==,!=,<,<=,>,>= - Conditions:
not_exists(),exists(),begins_with(),between() - Logical:
&(AND),|(OR),~(NOT)
TransactGetResult
jmespath(expr)- Apply JMESPath expression to transform results__len__()- Support forlen()__getitem__(index)- Support for indexing__iter__()- Support for iteration
Why Dynamixe?
- No ORM lock-in - Use Pydantic, dataclasses, or plain dicts
- Type-safe - Full type hints for IDE autocomplete
- Single-table design - Built for DynamoDB best practices
- Expression API - Composable, testable, readable
- Transactional - ACID operations with custom exceptions
- JMESPath support - Powerful result transformations
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dynamixe-0.1.0.tar.gz.
File metadata
- Download URL: dynamixe-0.1.0.tar.gz
- Upload date:
- Size: 69.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e6f4f96d55b4a111dd297aafe9361717aefff11e5732c7e77766e1c42f9fb225
|
|
| MD5 |
53b5dccb22cb37e26ccdc918f1032f39
|
|
| BLAKE2b-256 |
dd91c07b2b94db8e2197ff7a377b35467f9b8eb6d8782e51335b8001e25c6431
|
Provenance
The following attestation bundles were made for dynamixe-0.1.0.tar.gz:
Publisher:
python-publish.yaml on sergiors/dynamixe
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dynamixe-0.1.0.tar.gz -
Subject digest:
e6f4f96d55b4a111dd297aafe9361717aefff11e5732c7e77766e1c42f9fb225 - Sigstore transparency entry: 1185808618
- Sigstore integration time:
-
Permalink:
sergiors/dynamixe@65745045ab8d7d33cd72ae096a2935ea644f8cbe -
Branch / Tag:
refs/tags/0.1.0 - Owner: https://github.com/sergiors
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yaml@65745045ab8d7d33cd72ae096a2935ea644f8cbe -
Trigger Event:
release
-
Statement type:
File details
Details for the file dynamixe-0.1.0-py3-none-any.whl.
File metadata
- Download URL: dynamixe-0.1.0-py3-none-any.whl
- Upload date:
- Size: 13.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4d86d3b272787799e54d43281ff1d5ba8d6a7d8f21ac2441d1508f8bc84483a9
|
|
| MD5 |
d6e7eca1e27c20d8e34ac434d64b4180
|
|
| BLAKE2b-256 |
69f1d4b4ccafbe5fa98bb2a485ca754eaa0ab8946bd051a6e8e48477b2506547
|
Provenance
The following attestation bundles were made for dynamixe-0.1.0-py3-none-any.whl:
Publisher:
python-publish.yaml on sergiors/dynamixe
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
dynamixe-0.1.0-py3-none-any.whl -
Subject digest:
4d86d3b272787799e54d43281ff1d5ba8d6a7d8f21ac2441d1508f8bc84483a9 - Sigstore transparency entry: 1185808628
- Sigstore integration time:
-
Permalink:
sergiors/dynamixe@65745045ab8d7d33cd72ae096a2935ea644f8cbe -
Branch / Tag:
refs/tags/0.1.0 - Owner: https://github.com/sergiors
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yaml@65745045ab8d7d33cd72ae096a2935ea644f8cbe -
Trigger Event:
release
-
Statement type: