Python(boto3)에서의 DynamoDB 조건부 쓰기

조건부 쓰기put_item, update_item, 또는 delete_itemConditionExpression을 붙입니다: DynamoDB는 현재 항목에 대해 이를 평가하고 조건이 참일 때만 쓰기를 적용합니다 — 원자적으로, 읽기-수정-쓰기 경합 없이. 이것이 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_exists, attribute_not_exists, attribute_type, contains, begins_with, size, 그리고 비교 연산자(=, <>, <, >, <=, >=, BETWEEN, IN)와 AND/OR/NOT.
  • 두 가지 핵심 관용구:
    • 업데이트에서의 attribute_exists(#key) = "업데이트만, 절대 생성 안 함". 이것이 없으면 없는 키에 대한 update_item이 항목을 조용히 생성합니다(우발적 upsert 버그).
    • put에서의 attribute_not_exists(#key) = "생성만, 절대 덮어쓰기 안 함" — PutItem 페이지에 나와 있습니다.
  • 낙관적 잠금 — 항목을 읽고(버전 7), #version = :expectedVersion으로 쓰면서 8로 올립니다. 두 개의 동시 라이터가 모두 이길 수는 없습니다. 진 쪽은 ConditionalCheckFailedException을 받고, 다시 읽고, 새 버전에서 재시도합니다.
  • ReturnValuesOnConditionCheckFailure="ALL_OLD" — 실패한 검사 후 후속 get_item을 아끼도록 예외 응답(e.response)에 현재 항목을 담습니다. 이는 읽기 용량을 소비하지 않습니다. 실패한 조건부 쓰기도 여전히 쓰기 시도 비용을 청구합니다.
  • 리소스 API에서는 동일한 가드가 네이티브 Python 값을 사용하는 table.update_item(..., ConditionExpression=Attr("Version").eq(7) & Attr("Artist").exists())입니다.

Do it visually

조건 표현식은 DynamoDB Expression Builder가 만드는 바로 그것입니다 — 함수를 고르면 표현식 + 이름/값 맵을 실행 가능한 boto3 코드로 얻습니다.

손으로 입력한 자리 표시자 대신 생성되고 검토 가능한 표현식으로 항목을 편집하려면 — DynoTable을 다운로드하세요.

References

Last verified 2026-07-13 against the official AWS documentation linked above.

Console 없이 DynamoDB 작업하기

DynoTable은 DynamoDB를 위한 빠른 데스크톱 클라이언트입니다 — 테이블을 탐색하고, SQL 스타일 쿼리를 실행하고, 항목을 로컬에서 편집하세요.