PyDynamoDB
PyDynamoDB is a Python DB API 2.0 (PEP 249) client for Amazon DynamoDB, enabling interaction with DynamoDB using SQL-like syntax. It supports both DML operations via PartiQL and DDL operations through MySQL-like statements, and also provides a SQLAlchemy dialect. The current version is 0.8.2. The library has a consistent release cadence, with several updates in recent months, indicating active maintenance. [1, 6]
Warnings
- gotcha PyDynamoDB is a DB API 2.0 client, not an ORM like PynamoDB. They are distinct libraries with different APIs and features. Ensure you are using the correct library and its corresponding import paths.
- gotcha DynamoDB is a NoSQL database and differs significantly from relational databases. Common SQL patterns like normalizing data, simple primary key designs, and over-reliance on filter expressions lead to inefficient and costly operations. Filter expressions are applied *after* scan/query, impacting performance. [19, 22]
- gotcha DynamoDB does not natively support float types for numeric values; it expects decimal types. Passing standard Python floats can lead to unexpected behavior or data loss due to precision issues when interacting with the service. [20]
- gotcha Overusing DynamoDB transactions can lead to higher costs and performance issues, as each transactional write consumes twice the write capacity. Transactions are limited to 25 items and 4MB total size. Crossing updates on items in parallel transactions can also cause `TransactionCanceledException`. [21]
- gotcha Always wrap DynamoDB operations with try-catch blocks to gracefully handle failures, even though AWS SDKs (like boto3, which PyDynamoDB uses) handle internal retries with exponential backoff. Specific DynamoDB errors (e.g., `ConditionalCheckFailedException`, `ValidationException`, `ResourceNotFoundException`) require explicit handling. [20]
Install
-
pip install pydynamodb
Imports
- connect
from pydynamodb import connect
Quickstart
import os
from pydynamodb import connect
aws_access_key_id = os.environ.get('AWS_ACCESS_KEY_ID', 'YOUR_ACCESS_KEY')
aws_secret_access_key = os.environ.get('AWS_SECRET_ACCESS_KEY', 'YOUR_SECRET_KEY')
region_name = os.environ.get('AWS_DEFAULT_REGION', 'us-east-1')
try:
# Establish a connection
conn = connect(
aws_access_key_id=aws_access_key_id,
aws_secret_access_key=aws_secret_access_key,
region_name=region_name
)
# Create a cursor object
cursor = conn.cursor()
# Execute a DDL statement (MySQL-like syntax)
cursor.execute("CREATE TABLE IF NOT EXISTS MyTestTable (id STRING HASH KEY, name STRING)")
print("Table 'MyTestTable' created or already exists.")
# Execute a DML statement (PartiQL syntax)
cursor.execute("INSERT INTO MyTestTable VALUE {'id': ?, 'name': ?}", '1', 'Alice')
print("Inserted item 'Alice'.")
# Query data
cursor.execute("SELECT * FROM MyTestTable WHERE id = ?", '1')
result = cursor.fetchall()
print(f"Queried result: {result}")
# Clean up (optional)
# cursor.execute("DROP TABLE MyTestTable")
# print("Table 'MyTestTable' dropped.")
# Close the connection
cursor.close()
conn.close()
except Exception as e:
print(f"An error occurred: {e}")