TypeError: Float types are not supported. Use Decimal types instead. は、boto3 で DynamoDB に保存する値の中に、Python の小数(float)が入っていたときのエラーです。 DynamoDB の数値は、boto3 では int か decimal.Decimal で渡す決まりになっています。

table.put_item(Item={"id": "p1", "price": 1.5})   # ← TypeError

直し方は、小数を Decimal("1.5") にすることです。 文字列から作るのがポイントです。

from decimal import Decimal
table.put_item(Item={"id": "p1", "price": Decimal("1.5")})   # OK

そして、読み出した数値は Decimal で返ってくるので、そのまま json.dumps すると、今度は逆向きのエラーになります。

エラー いつ 直し方
TypeError: Float types are not supported. Use Decimal types instead. 保存するとき(float を渡した) Decimal("1.5")、JSON なら json.loads(..., parse_float=Decimal)
TypeError: Object of type Decimal is not JSON serializable 読み出した値を json.dumps したとき json.dumps(item, default=...) で変換
Inexact: [<class 'decimal.Inexact'>, <class 'decimal.Rounded'>] Decimal(1.1) のように float から作った Decimal(str(1.1)) か Decimal("1.1")
TypeError: Infinity and NaN not supported Decimal("NaN") を保存した 保存前に値を確かめる

確認環境:boto3 1.43.111・Python 3.11(Linux)。DynamoDB の代わりに moto 5.2.4 のモックを使いました。表のエラーは、どれも boto3 が DynamoDB へ送る前の変換で出たものです(確認日 2026年10月12日)。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Float types are not supportedの直し方|DynamoDB」

なぜ float は使えないのか:boto3 の型の対応表

boto3 のドキュメントの、Table リソースで使える Python の型と DynamoDB の型の対応表です。数値(N)になるのは int と decimal.Decimal だけで、float は入っていません。

Python の型 DynamoDB の型
str String(S)
int Number(N)
decimal.Decimal Number(N)
bool Boolean(BOOL)
None Null(NULL)
list List(L)
dict Map(M)
set(文字列・数値・Binary) SS・NS・BS

float は 2進数で近い値を持つので、1.1 が正確には 1.1 ではありません。そのまま送ると値がずれるため、boto3 は float を受け付けず、Decimal を求めます。

原因① 小数をそのまま入れた(入れ子も同じ)

一番上の項目だけでなく、Map(dict)や List の中の float でも同じエラーでした。

渡した Item 結果
{"id": "p1", "price": 1.5} TypeError: Float types are not supported
{"id": "p1", "spec": {"weight": 0.25}} TypeError(dict の中)
{"id": "p1", "scores": [1, 2.5]} TypeError(list の中)
{"id": "p1", "price": 1200}(int) 保存できた
{"id": "p2", "price": Decimal("1.1")} 保存できた

原因② JSON を json.loads してそのまま保存した

API の入力や S3 のファイルなど、JSON を json.loads すると、小数は float になります。 それをそのまま put_item すると、このエラーになりました。

body = '{"id":"p3","price":980.5,"spec":{"weight":0.25},"tags":["a"]}'

table.put_item(Item=json.loads(body))                         # ← TypeError
table.put_item(Item=json.loads(body, parse_float=Decimal))    # OK

parse_float=Decimal を付けると、JSON の中の小数が、入れ子の中まで全部 Decimal になります。 1つずつ変換するより確実です。

原因③ Decimal(1.1) と書いた(float から作った)

Decimal(1.1) は、float の 1.1 を「そのまま正確に」Decimal にします。 そのため、次のような長い値になりました。

>>> Decimal(1.1)
Decimal('1.100000000000000088817841970012523233890533447265625')
>>> Decimal(str(1.1))
Decimal('1.1')

この値を保存すると、Float types ではなく別のエラーになりました。

decimal.Inexact: [<class 'decimal.Inexact'>, <class 'decimal.Rounded'>]

AWS のドキュメントには「数値は最大38桁の精度で、超えると例外になる」とあり、それを超える桁を丸めようとして止まったものです。float の変数を Decimal にするときは、Decimal(str(値)) と文字列を通します。

price = 1.1                       # float で受け取った値
item = {"id": "p2", "price": Decimal(str(price))}

読み出すと Decimal で返ってくる

保存した Decimal("1.1") と 10(int)を get_item で読み出すと、どちらも Decimal で返ってきました。 整数で保存しても Decimal('10') です。

>>> table.get_item(Key={"id": "p2"})["Item"]
{'id': 'p2', 'price': Decimal('1.1'), 'stock': Decimal('10')}

これを json.dumps すると、逆向きのエラーになります。

TypeError: Object of type Decimal is not JSON serializable

直し方:default で変換する

json.dumps の default に、Decimal を数値に変える関数を渡します。 整数なら int、小数なら float にすると、JSON では元の見た目の数値になりました。

import json
from decimal import Decimal

def decimal_default(o):
    if isinstance(o, Decimal):
        return int(o) if o == o.to_integral_value() else float(o)
    raise TypeError(f"Object of type {type(o).__name__} is not JSON serializable")

json.dumps(item, default=decimal_default, ensure_ascii=False)
# {"id": "p2", "price": 1.1, "stock": 10}
書き方 結果 向いている場面
default=decimal_default(上の関数) {"price": 1.1, "stock": 10} 画面や API に数値で返す
default=str {"price": "1.1", "stock": "10"} 桁を落とさず文字列で渡したい(金額など)

金額など、float にすると誤差が困る値は default=str で文字列にして渡すのが安全です。受け取る側と、数値か文字列かを決めておきます。

Lambda で返すときは、書き方で結果が違った

Lambda の Python ランタイム(AWS が公開しているランタイムクライアント awslambdaric 4.2.0)で、Decimal を含む dict を返すところを再現しました。

ハンドラの戻り値 結果
return item(Decimal を含む dict をそのまま) 成功。{"id": "p2", "price": 1.1, "stock": 10} に変換された
return {"statusCode": 200, "body": json.dumps(item)} 失敗。TypeError: Object of type Decimal is not JSON serializable

ランタイムクライアントは、戻り値の Decimal を数値に変換して返していました。 一方、API Gateway 向けに body を文字列にしようとして自分で json.dumps すると、そこでエラーになります。API Gateway と組み合わせるときは、body を作る json.dumps に default を付けます。

def lambda_handler(event, context):
    item = table.get_item(Key={"id": event["pathParameters"]["id"]})["Item"]
    return {
        "statusCode": 200,
        "headers": {"Content-Type": "application/json"},
        "body": json.dumps(item, default=decimal_default, ensure_ascii=False),
    }

client と resource で、渡し方が違う

ここまでの話は、boto3.resource("dynamodb").Table(...)(resource)の場合です。 boto3.client("dynamodb")(client)では、型を自分で書く形になり、Python の値をそのまま渡すと別のエラーになりました。

client.get_item(TableName="Products", Key={"id": "p2"})
# ParamValidationError: Invalid type for parameter Key.id, value: p2, type: <class 'str'>, valid types: <class 'dict'>

client.get_item(TableName="Products", Key={"id": {"S": "p2"}})["Item"]
# {'id': {'S': 'p2'}, 'price': {'N': '1.1'}, 'stock': {'N': '10'}}
resource(Table) client
渡し方 {"price": Decimal("1.1")} {"price": {"N": "1.1"}}
返り値 Decimal('1.1') {'N': '1.1'}(文字列)
float TypeError: Float types are not supported 数値は文字列で書くので起きない

client と resource の違いは、関連記事「boto3 client・resource・sessionの違いと認証の優先順位」で扱っています。

よくある質問

Q. 全部 int にして保存すればいいですか。 A. 金額を「円」、重さを「グラム」のように整数の単位で持てるなら、int で保存すると Decimal の扱いが楽になります。読み出すと Decimal で返ってくる点は同じです。

Q. pandas の DataFrame から保存するときは? A. pandas(3.0.6)の DataFrame を to_dict した値を変換すると、小数の列が float のため同じエラーになりました。json.loads(df.to_json(orient="records"), parse_float=Decimal) のように、JSON を通して Decimal にする方法があります。

Q. datetime も保存できません。 A. AWS のドキュメントでも、DynamoDB に日時の型は無く、ISO 8601 の文字列("2026-10-12T09:00:00Z")か、エポック秒の数値で持つ方法が紹介されています。エポック秒なら TTL(期限切れの項目の自動削除)にも使えます。json.dumps のエラーは、関連記事「datetime is not JSON serializableの直し方」で扱っています。

Q. 数値の範囲はありますか。 A. 有効桁数 38 桁まで、正の数は 1E-130 から 9.9999…E+125 までです。Decimal("1" + "0"*40) を保存しようとすると、decimal.Rounded で止まりました。DynamoDB の使い方全般は、関連記事「DynamoDBの使い方|AWS CLIとboto3のquery・scan」で扱っています。

まとめ

  • Float types are not supported は、保存する値に float が入っていた。入れ子の中も対象
  • 小数は Decimal("1.5")。JSON からなら json.loads(..., parse_float=Decimal)
  • Decimal(1.1) は長い値になって Inexact。float からは Decimal(str(値))
  • 読み出した数値は int でも Decimal。json.dumps は default= で変換
  • Lambda は Decimal を返しても変換されたが、自分で json.dumps する body は要注意

参考・出典

確認日はいずれも 2026年10月12日です。

  • Boto3 ドキュメント「DynamoDB customization reference」(Valid DynamoDB types):https://docs.aws.amazon.com/boto3/latest/reference/customizations/dynamodb.html
  • Amazon DynamoDB デベロッパーガイド「Supported data types and naming rules」(Number):https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html
  • Python ドキュメント「json」(parse_float・default):https://docs.python.org/3/library/json.html
  • Python ドキュメント「decimal」:https://docs.python.org/3/library/decimal.html

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Float types are not supportedの直し方|DynamoDB」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?