Float types are not supported. Use Decimal types instead.
TL;DR — boto3 lanzó un TypeError de Python porque pasaste un float a DynamoDB. DynamoDB almacena los números como decimales de precisión arbitraria (hasta 38 dígitos), y los floats binarios no pueden representarlos con exactitud — por eso boto3 los rechaza. Convierte a decimal.Decimal antes de escribir, idealmente mediante str() para no heredar el redondeo del float.
Qué significa
TypeError: Float types are not supported. Use Decimal types instead.Este es un error del lado del cliente lanzado por boto3 (el AWS SDK para Python), no una respuesta del servicio DynamoDB — el serializador del SDK rechaza el float antes de que la solicitud llegue a enviarse. El tipo N de DynamoDB contiene un número decimal con hasta 38 dígitos de precisión; el float de Python es IEEE-754 binario, que no puede representar esos valores sin pérdida. boto3 falla ruidosamente en lugar de almacenar silenciosamente una aproximación.
Por qué ocurre
- Escribir un
floaten crudo — un precio30.51, una media calculada, un resultado dejson.loads()(los números JSON con decimales se convierten en floats de Python). - Floats anidados — un float enterrado dentro de un dict/list que estás guardando; boto3 recorre toda la estructura y rechaza el primero.
- Resultados aritméticos —
total / count,sum(...), o cualquier división que produzca un float. - Datos de terceros (pandas, la respuesta de una API) que te entregan valores numpy/
float64.
Cómo solucionarlo
- Convierte a
decimal.Decimalantes de escribir:from decimal import Decimal table.put_item(Item={'pk': 'ORDER#1', 'total': Decimal('30.51')}) - Construye el
Decimala partir de unastr, no del float —Decimal(30.51)hereda el error del float binario (30.510000000000001...);Decimal(str(30.51))te da exactamente30.51. - Convierte recursivamente para datos anidados — recorre el dict/list y convierte cada float en
Decimal(str(x))antes deput_item. Un patrón común esjson.loads(json.dumps(obj), parse_float=Decimal). - Al leer de vuelta, los atributos numéricos salen como
Decimal; conviértelos afloat/inten el borde de tu aplicación si necesitas tipos nativos. - Para valores más allá de 38 dígitos de precisión (IDs, enteros enormes), almacénalos como cadenas en lugar de números — ver desbordamiento numérico.
FAQ
¿Por qué DynamoDB no acepta floats de Python? Los números de DynamoDB son decimales de precisión arbitraria (hasta 38 dígitos). El float de Python es IEEE-754 binario y no puede representar la mayoría de los decimales con exactitud, así que boto3 se niega a almacenar una aproximación con pérdida y lanza "Float types are not supported. Use Decimal types instead."
¿Cómo convierto un float a Decimal correctamente para DynamoDB? Construye el Decimal a partir de la forma de cadena: Decimal(str(value)), no Decimal(value). Decimal(30.51) arrastra el error de redondeo binario del float, mientras que Decimal(str(30.51)) es exactamente 30.51. Para estructuras anidadas, usa json.loads(json.dumps(obj), parse_float=Decimal).
Reproducirlo
El rechazo ocurre en el serializador de boto3, antes de que se envíe nada:
from boto3.dynamodb.types import TypeSerializer
TypeSerializer().serialize(1.5)Salida real:
TypeError: Float types are not supported. Use Decimal types instead.Fíjate en la clase: esto es un TypeError normal de boto3, no un error del servicio DynamoDB. Nada llegó a AWS, así que no hay estado HTTP, ni capacidad consumida, ni petición que reintentar — y un manejador except ClientError no lo capturará.
Errores relacionados
- Number overflow — un valor más allá del rango de magnitud de 38 dígitos de DynamoDB.
- SerializationException — un desajuste de tipo de cable número/cadena.
- Aprende: Tipos de datos de DynamoDB
Referencias
- Supported data types and naming rules in Amazon DynamoDB — Developer Guide
- boto3/dynamodb/types.py — boto3 source (TypeSerializer)
- Amazon DynamoDB — AWS SDK for Python (Boto3) guide
Verificado por última vez el 2026-07-13 contra la documentación oficial de AWS enlazada arriba.
Reproducido el 2026-07-26 contra boto3 1.43.56 / botocore 1.43.56 — la salida de arriba es literal.