Python (boto3) での DynamoDB 条件付き書き込み

条件付き書き込みは、put_itemupdate_itemdelete_itemConditionExpression を付けます。DynamoDB はそれを現在のアイテムに対して評価し、条件が成立する場合にのみ書き込みを適用します。アトミックで、read-modify-write の競合はありません。これは DynamoDB の楽観的ロックのプリミティブです。この例では、バージョンチェックで更新をガードします。

Code

import boto3

client = boto3.client("dynamodb")

# Update the item only if nobody changed it since we read version 7.
try:
    client.update_item(
        TableName="Music",
        Key={"Artist": {"S": "Arturo Sandoval"}, "SongTitle": {"S": "Cubano Chant"}},
        UpdateExpression="SET #upd0 = :updValue0, #version = :newVersion",
        ConditionExpression="attribute_exists(#cond0) AND #version = :expectedVersion",
        ExpressionAttributeNames={"#upd0": "Genre", "#version": "Version", "#cond0": "Artist"},
        ExpressionAttributeValues={
            ":updValue0": {"S": "Latin Jazz"},
            ":expectedVersion": {"N": "7"},
            ":newVersion": {"N": "8"},
        },
        ReturnValuesOnConditionCheckFailure="ALL_OLD",
    )
    print("Updated to version 8")
except client.exceptions.ConditionalCheckFailedException as e:
    # With ReturnValuesOnConditionCheckFailure="ALL_OLD", the current item
    # rides back on the exception — no extra read to see what beat you.
    print("Lost the race — item is now:", e.response.get("Item"))

Explanation

  • ConditionExpression — 書き込みとアトミックに、保存されたアイテムに対してチェックされます。利用可能な関数: attribute_existsattribute_not_existsattribute_typecontainsbegins_withsize、加えて比較演算子(=<><><=>=BETWEENIN)と AND/OR/NOT
  • 2つの主力イディオム:
    • 更新での attribute_exists(#key) = 「更新のみ、決して作成しない」。これがないと、存在しないキーへの update_item はアイテムを静かに作成します(意図しないアップサートのバグ)。
    • プットでの attribute_not_exists(#key) = 「作成のみ、決して上書きしない」— PutItem ページで示しています。
  • 楽観的ロック — アイテム(バージョン7)を読み取り、8 に上げながら #version = :expectedVersion で書き込みます。2つの並行する書き込み側が両方とも勝つことはありません。負けた側は ConditionalCheckFailedException を受け取り、再読み取りして新しいバージョンでリトライします。
  • ReturnValuesOnConditionCheckFailure="ALL_OLD"現在のアイテムを例外レスポンス(e.response)に載せ、失敗チェック後の後続 get_item を省きます。読み取りキャパシティは消費しません。失敗した条件付き書き込みでも、書き込みの試行分は課金されます。
  • リソースAPI では、同じガードはネイティブな Python 値を使って table.update_item(..., ConditionExpression=Attr("Version").eq(7) & Attr("Artist").exists()) になります。

Do it visually

条件式はまさに DynamoDB Expression Builder が構築するものです。関数を選べば、式と name/value マップが実行可能な boto3 コードとして得られます。

手入力のプレースホルダーの代わりに、生成された、レビュー可能な式でアイテムを編集するには — DynoTable をダウンロードしてください。

References

最終検証日 2026-07-13、上記にリンクした公式 AWS ドキュメントに照らして確認しました。

Console なしで DynamoDB を扱う

DynoTable は DynamoDB 向けの高速なデスクトップクライアントです — テーブルを閲覧し、SQL スタイルのクエリを実行し、アイテムをローカルで編集できます。