Type mismatches, especially floats and Decimals, are the first errors every Python developer hits.
DynamoDB attribute values have one of these types:
- scalars: S (string), N (number), B (binary), BOOL, NULL
- documents: M (map, a nested object) and L (list, any mix of types)
- sets: SS, NS, BS (unique strings, numbers or binaries; never empty)
Key attributes must be S, N or B. Numbers are sent as strings and stored with up to 38 digits of precision, so they are exact decimals rather than floats.
boto3 has two interfaces. The low-level client speaks the wire format, where every value is wrapped with its type: {"total": {"N": "35"}}. The higher-level resource (boto3.resource("dynamodb").Table(...)) converts automatically between Python and DynamoDB types:
strto S,boolto BOOL,Noneto NULL,dictto M,listto L,setto a set type,bytesto B- numbers come back as
decimal.Decimal, and you must sendintorDecimal, not `float`
Passing a float raises TypeError: Float types are not supported. Convert with Decimal(str(x)), or keep money in integer cents. When returning items as JSON from an API, convert Decimals back (e.g. a custom default= in json.dumps).
The resource interface is the most readable for scripts; the client offers every API and is required for some newer features.
Example
from decimal import Decimal
import boto3
table = boto3.resource("dynamodb").Table("Orders")
table.put_item(Item={
"customer_id": "c1", "order_id": "2025-03-01#A17",
"total": Decimal("35.90"), # not 35.90 (float raises TypeError)
"paid": True,
"items": [{"sku": "pen", "qty": 2}], # list of maps
"tags": {"gift", "express"}, # string set
})
item = table.get_item(Key={"customer_id": "c1", "order_id": "2025-03-01#A17"})["Item"]
print(item["total"], type(item["total"]).__name__) # 35.90 Decimal
print(item["items"][0]["qty"]) # 2 (also a Decimal)Remember
- Types: S, N, B, BOOL, NULL, M, L and the sets SS/NS/BS
- Key attributes must be string, number or binary
- The boto3 resource maps Python types automatically; numbers come back as Decimal
- Never send floats: use Decimal or integers
Watch out for
- Passing a Python float to put_item and getting 'Float types are not supported'.