1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Boto3】DynamoDB PutItemはclientとresourceでかなり違った

1
Last updated at Posted at 2026-04-06

結論

APIレスポンスをDynamoDBに入れたいなら、
最初は client.put_item より resource.Table.put_item の方が進めやすかったです。

client はスキーマ定義が必要です。
resource はdict感覚で書きやすいです。
扱い易さという点では、かなり差がありました。

エピソード

Lambda上のPythonで、APIの取得データをDynamoDBに保存しようとしました。

最初はAIに聞かず、
Boto3のリファレンスを読みながら進めました。

最初に見つけたのは client.put_item でした。
ただ、JSONをそのままDBに格納出来る訳ではなく、少し手が止まりました。

ハウツー

1. まず clientresource を分けて考える

Boto3でDynamoDBに書き込む入口は、だいたいこの2つです。

  • boto3.client("dynamodb")
  • boto3.resource("dynamodb").Table("テーブル名")

ここを最初に分けておくと楽です。

2. client.put_item は型付きで書く

client.put_item は、
DynamoDB用の型情報を含めて渡します。

import boto3

client = boto3.client("dynamodb")

client.put_item(
    TableName="sample-table",
    Item={
        "id": {"S": "user-001"},
        "name": {"S": "Taro"},
        "age": {"N": "30"}
    }
)

"S" は文字列型です。
"N" は数値型です。

"N" は「数値型」を表します。
ただし、値そのものは 30 ではなく "30" のように文字列で渡します

理由

JSONを入れたいのに、
先にDynamoDB用の書式を作る必要があります。

PutItem → 型付きで書く必要あり
JSONそのままでは入れにくい

まずインスタントに保存したかったので、
この仕様はきつかったです。

レスポンスJSONの階層が深いので、
resourceの利用は断念しました。

3. 最初は resource.Table.put_item を使う

resource.Table.put_item は、
Pythonのdictに近い形で書けます。

import boto3

dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table("sample-table")

table.put_item(
    Item={
        "id": "user-001",
        "name": "Taro",
        "age": 30
    }
)

Boto3は新しい機能追加を resource ではなく client 側で提供する方針です。
それでも、クイックスタートしてまず保存を通したい段階では、resource はかなり有用でした。

理由

まずやりたいのは保存です。
型表現より、データそのものに集中できます。

4. APIレスポンスは最初はまとめて格納

最初から細かくパースせず、
主キーを決めて、レスポンス全体を1つの属性に入れてしまいました。
APIレスポンス記録がDBの用途です。

import json
import boto3

dynamodb = boto3.resource("dynamodb")
table = dynamodb.Table("sample-table")

def lambda_handler(event, context):
    api_response = {
        "timestamp": "2026-04-06T12:34:56Z",
        "profile": {
            "name": "Taro",
            "age": 30
        },
        "status": "active"
    }

    item = {
        "timestamp": api_response["timestamp"],
        "data": api_response
    }

    table.put_item(Item=item)

    return {
        "statusCode": 200,
        "body": json.dumps({"message": "saved"})
    }

APIレスポンスに float が混ざると、
そのままではハマることがあります。

DynamoDBでは、Pythonの float ではなく
Decimal に変換して扱うのが定番です。

from decimal import Decimal
import json

normalized = json.loads(json.dumps(api_response), parse_float=Decimal)

5. 先に知っておくと楽なこと

  • 主キーは必須
  • put_item は部分更新ではない
  • 同じ主キーなら置き換え
  • 最初は resource の方が入りやすい

おわりに

APIレスポンスをまずDynamoDBに入れたいなら、
最初は resource.Table.put_item から入る方が進めやすかったです。

client.put_item で止まりかけたら、
いったん resource 側を見るのがおすすめです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?