0
# DynamoDB Operations
1
2
High-level DynamoDB functionality including condition expressions, type serialization, and table operations. Provides pythonic interfaces for DynamoDB's attribute-value model, making it easier to work with DynamoDB's unique data types and query patterns.
3
4
## Capabilities
5
6
### Condition Expressions
7
8
Condition classes for building DynamoDB filter expressions, key conditions, and update conditions. These provide a pythonic way to construct the condition expressions required by DynamoDB operations.
9
10
```python { .api }
11
from boto3.dynamodb.conditions import Key, Attr
12
13
class Key:
14
"""
15
Key attribute reference for DynamoDB key conditions.
16
Used in query operations to specify which partition key and sort key values to retrieve.
17
"""
18
19
def __init__(self, name: str):
20
"""
21
Parameters:
22
- name: The key attribute name
23
"""
24
25
def eq(self, value) -> ConditionBase:
26
"""Create equality condition (key = value)."""
27
28
def lt(self, value) -> ConditionBase:
29
"""Create less than condition (key < value)."""
30
31
def lte(self, value) -> ConditionBase:
32
"""Create less than or equal condition (key <= value)."""
33
34
def gt(self, value) -> ConditionBase:
35
"""Create greater than condition (key > value)."""
36
37
def gte(self, value) -> ConditionBase:
38
"""Create greater than or equal condition (key >= value)."""
39
40
def begins_with(self, value) -> ConditionBase:
41
"""Create begins with condition for string keys."""
42
43
def between(self, low_value, high_value) -> ConditionBase:
44
"""Create between condition (low_value <= key <= high_value)."""
45
46
class Attr:
47
"""
48
General attribute reference for DynamoDB filter conditions.
49
Used in filter expressions to specify conditions on non-key attributes.
50
"""
51
52
def __init__(self, name: str):
53
"""
54
Parameters:
55
- name: The attribute name
56
"""
57
58
def eq(self, value) -> ConditionBase:
59
"""Create equality condition (attribute = value)."""
60
61
def ne(self, value) -> ConditionBase:
62
"""Create not equal condition (attribute <> value)."""
63
64
def lt(self, value) -> ConditionBase:
65
"""Create less than condition."""
66
67
def lte(self, value) -> ConditionBase:
68
"""Create less than or equal condition."""
69
70
def gt(self, value) -> ConditionBase:
71
"""Create greater than condition."""
72
73
def gte(self, value) -> ConditionBase:
74
"""Create greater than or equal condition."""
75
76
def begins_with(self, value) -> ConditionBase:
77
"""Create begins with condition for string attributes."""
78
79
def between(self, low_value, high_value) -> ConditionBase:
80
"""Create between condition."""
81
82
def is_in(self, values: List) -> ConditionBase:
83
"""Create IN condition (attribute IN (value1, value2, ...))."""
84
85
def exists(self) -> ConditionBase:
86
"""Create attribute exists condition."""
87
88
def not_exists(self) -> ConditionBase:
89
"""Create attribute does not exist condition."""
90
91
def contains(self, value) -> ConditionBase:
92
"""Create contains condition for strings and sets."""
93
94
def size(self) -> Size:
95
"""Return Size object for size-based conditions."""
96
97
def attribute_type(self, type_name: str) -> ConditionBase:
98
"""Create attribute type condition to check attribute's data type."""
99
100
class Size:
101
"""
102
Size-based conditions for DynamoDB attributes.
103
Used to create conditions based on the size of strings, sets, lists, or maps.
104
"""
105
106
def eq(self, value: int) -> ConditionBase:
107
"""Create size equals condition."""
108
109
def ne(self, value: int) -> ConditionBase:
110
"""Create size not equal condition."""
111
112
def lt(self, value: int) -> ConditionBase:
113
"""Create size less than condition."""
114
115
def lte(self, value: int) -> ConditionBase:
116
"""Create size less than or equal condition."""
117
118
def gt(self, value: int) -> ConditionBase:
119
"""Create size greater than condition."""
120
121
def gte(self, value: int) -> ConditionBase:
122
"""Create size greater than or equal condition."""
123
124
def between(self, low_value: int, high_value: int) -> ConditionBase:
125
"""Create size between condition."""
126
```
127
128
### Condition Base Classes and Logical Operators
129
130
Base classes for conditions and logical operators for combining multiple conditions.
131
132
```python { .api }
133
class ConditionBase:
134
"""
135
Base class for all DynamoDB conditions.
136
Supports logical operations to combine conditions.
137
"""
138
139
def __and__(self, other: ConditionBase) -> And:
140
"""Combine conditions with logical AND (&)."""
141
142
def __or__(self, other: ConditionBase) -> Or:
143
"""Combine conditions with logical OR (|)."""
144
145
def __invert__(self) -> Not:
146
"""Negate condition with logical NOT (~)."""
147
148
class And(ConditionBase):
149
"""Logical AND combination of conditions."""
150
151
class Or(ConditionBase):
152
"""Logical OR combination of conditions."""
153
154
class Not(ConditionBase):
155
"""Logical NOT negation of a condition."""
156
```
157
158
### Type Serialization
159
160
Classes for converting between Python data types and DynamoDB's attribute value format.
161
162
```python { .api }
163
from boto3.dynamodb.types import Binary, TypeSerializer, TypeDeserializer
164
165
class Binary:
166
"""
167
Wrapper for binary data in DynamoDB.
168
169
DynamoDB requires binary data to be explicitly marked as binary type.
170
This class wraps bytes objects to indicate they should be stored as binary.
171
"""
172
173
def __init__(self, value: bytes):
174
"""
175
Parameters:
176
- value: Binary data as bytes
177
"""
178
self.value = value
179
180
class TypeSerializer:
181
"""
182
Serializes Python data types to DynamoDB attribute value format.
183
184
Converts standard Python types (str, int, float, bool, list, dict, set, bytes)
185
to the attribute value format required by DynamoDB's low-level API.
186
"""
187
188
def serialize(self, obj) -> Dict[str, Any]:
189
"""
190
Serialize a Python value to DynamoDB format.
191
192
Parameters:
193
- obj: Python value to serialize
194
195
Returns:
196
Dictionary in DynamoDB attribute value format (e.g., {'S': 'string_value'})
197
"""
198
199
class TypeDeserializer:
200
"""
201
Deserializes DynamoDB attribute values to Python data types.
202
203
Converts DynamoDB's attribute value format back to standard Python types.
204
"""
205
206
def deserialize(self, value: Dict[str, Any]):
207
"""
208
Deserialize a DynamoDB attribute value to Python format.
209
210
Parameters:
211
- value: DynamoDB attribute value (e.g., {'S': 'string_value'})
212
213
Returns:
214
Python value in native type
215
"""
216
```
217
218
### DynamoDB Type Constants
219
220
Constants representing DynamoDB data types for use in type checking and serialization.
221
222
```python { .api }
223
# DynamoDB type identifiers
224
STRING = 'S' # String type
225
NUMBER = 'N' # Number type
226
BINARY = 'B' # Binary type
227
STRING_SET = 'SS' # String set type
228
NUMBER_SET = 'NS' # Number set type
229
BINARY_SET = 'BS' # Binary set type
230
NULL = 'NULL' # Null type
231
BOOLEAN = 'BOOL' # Boolean type
232
MAP = 'M' # Map (dictionary) type
233
LIST = 'L' # List type
234
235
# Decimal context for DynamoDB number precision
236
DYNAMODB_CONTEXT: Context # Decimal context with DynamoDB-compatible precision
237
238
# Valid binary data types
239
BINARY_TYPES = (bytearray, bytes)
240
```
241
242
## Usage Examples
243
244
### Basic Condition Usage
245
246
```python
247
import boto3
248
from boto3.dynamodb.conditions import Key, Attr
249
250
dynamodb = boto3.resource('dynamodb')
251
table = dynamodb.Table('my-table')
252
253
# Query with key condition
254
response = table.query(
255
KeyConditionExpression=Key('pk').eq('USER#123') & Key('sk').begins_with('ORDER#')
256
)
257
258
# Scan with filter condition
259
response = table.scan(
260
FilterExpression=Attr('status').eq('active') & Attr('created_date').gte('2023-01-01')
261
)
262
```
263
264
### Complex Condition Expressions
265
266
```python
267
from boto3.dynamodb.conditions import Key, Attr
268
269
# Complex key condition for query
270
key_condition = Key('pk').eq('USER#123') & Key('sk').between('ORDER#2023-01-01', 'ORDER#2023-12-31')
271
272
# Complex filter with multiple conditions
273
filter_condition = (
274
Attr('status').is_in(['active', 'pending']) &
275
Attr('amount').gt(100) &
276
Attr('tags').contains('priority') &
277
~Attr('deleted').exists() # NOT exists using ~ operator
278
)
279
280
response = table.query(
281
KeyConditionExpression=key_condition,
282
FilterExpression=filter_condition
283
)
284
```
285
286
### Type Serialization Example
287
288
```python
289
from boto3.dynamodb.types import Binary, TypeSerializer, TypeDeserializer
290
291
# Create binary data
292
binary_data = Binary(b'Hello, World!')
293
294
# Serialize Python data to DynamoDB format
295
serializer = TypeSerializer()
296
item_data = {
297
'name': 'John Doe',
298
'age': 30,
299
'active': True,
300
'tags': {'priority', 'vip'},
301
'metadata': {'created': '2023-01-01', 'version': 1},
302
'profile_image': binary_data
303
}
304
305
# Serialize the entire item
306
serialized_item = {k: serializer.serialize(v) for k, v in item_data.items()}
307
308
# Deserialize DynamoDB response back to Python
309
deserializer = TypeDeserializer()
310
python_item = {k: deserializer.deserialize(v) for k, v in serialized_item.items()}
311
```
312
313
### Working with Sets and Lists
314
315
```python
316
from boto3.dynamodb.conditions import Attr
317
318
# Query items where a set contains a specific value
319
response = table.scan(
320
FilterExpression=Attr('categories').contains('electronics')
321
)
322
323
# Query items based on list size
324
response = table.scan(
325
FilterExpression=Attr('items').size().gt(5)
326
)
327
328
# Query items with nested attribute conditions
329
response = table.scan(
330
FilterExpression=Attr('address.city').eq('New York')
331
)
332
```
333
334
### Update Expressions with Conditions
335
336
```python
337
from boto3.dynamodb.conditions import Attr
338
339
# Conditional update - only update if condition is met
340
try:
341
response = table.update_item(
342
Key={'pk': 'USER#123', 'sk': 'PROFILE'},
343
UpdateExpression='SET #status = :status, last_updated = :timestamp',
344
ConditionExpression=Attr('version').eq(1), # Only update if version is 1
345
ExpressionAttributeNames={'#status': 'status'},
346
ExpressionAttributeValues={
347
':status': 'inactive',
348
':timestamp': '2023-12-01T10:00:00Z'
349
},
350
ReturnValues='ALL_NEW'
351
)
352
except ClientError as e:
353
if e.response['Error']['Code'] == 'ConditionalCheckFailedException':
354
print("Update failed: condition not met")
355
else:
356
raise
357
```
358
359
### Transaction Operations with Conditions
360
361
```python
362
from boto3.dynamodb.conditions import Key, Attr
363
364
dynamodb = boto3.resource('dynamodb')
365
366
# Transactional write with conditions
367
try:
368
dynamodb.meta.client.transact_write_items(
369
TransactItems=[
370
{
371
'Update': {
372
'TableName': 'accounts',
373
'Key': {'account_id': {'S': 'account1'}},
374
'UpdateExpression': 'SET balance = balance - :amount',
375
'ConditionExpression': 'balance >= :amount',
376
'ExpressionAttributeValues': {':amount': {'N': '100'}}
377
}
378
},
379
{
380
'Update': {
381
'TableName': 'accounts',
382
'Key': {'account_id': {'S': 'account2'}},
383
'UpdateExpression': 'SET balance = balance + :amount',
384
'ExpressionAttributeValues': {':amount': {'N': '100'}}
385
}
386
}
387
]
388
)
389
except ClientError as e:
390
if e.response['Error']['Code'] == 'TransactionCanceledException':
391
print("Transaction failed: conditions not met")
392
else:
393
raise
394
```