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 float en crudo — un precio 30.51, una media calculada, un resultado de json.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éticostotal / 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

  1. Convierte a decimal.Decimal antes de escribir:
    from decimal import Decimal
    table.put_item(Item={'pk': 'ORDER#1', 'total': Decimal('30.51')})
  2. Construye el Decimal a partir de una str, no del floatDecimal(30.51) hereda el error del float binario (30.510000000000001...); Decimal(str(30.51)) te da exactamente 30.51.
  3. Convierte recursivamente para datos anidados — recorre el dict/list y convierte cada float en Decimal(str(x)) antes de put_item. Un patrón común es json.loads(json.dumps(obj), parse_float=Decimal).
  4. Al leer de vuelta, los atributos numéricos salen como Decimal; conviértelos a float/int en el borde de tu aplicación si necesitas tipos nativos.
  5. 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

Referencias

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.

Trabaja con DynamoDB sin la Consola

Un cliente de escritorio rápido para DynamoDB que ejecuta el SQL real que DynamoDB no puede — JOINs, GROUP BY, agregaciones — con edición visual y un agente de IA con tus propias claves de Bedrock.

Prueba gratuita de 30 días, sin tarjeta — después, el plan Free sin límite de tiempo.