AWS CLI를 사용한 DynamoDB 조건부 쓰기

조건부 쓰기는 셸에서 보내기는 간단하지만 결과를 읽는 쪽이 껄끄럽습니다. 실패했을 때 정작 흥미로운 결과가 출력이 아니라 오류로 도착하기 때문입니다. DynamoDB 조건 표현식이 표현식으로 무엇을 말할 수 있는지 다루고, 이 페이지는 CLI에서 조건부 쓰기를 실행하고 실패에서 진 항목을 꺼내오는 방법을 다룹니다.

코드

aws dynamodb update-item \
  --table-name 'Music' \
  --key '{"Artist":{"S":"Arturo Sandoval"},"SongTitle":{"S":"Cubano Chant"}}' \
  --update-expression 'SET #upd0 = :updValue0, #version = :newVersion' \
  --condition-expression 'attribute_exists(#cond0) AND #version = :expectedVersion' \
  --expression-attribute-names '{"#upd0":"Genre","#version":"Version","#cond0":"Artist"}' \
  --expression-attribute-values '{":updValue0":{"S":"Latin Jazz"},":expectedVersion":{"N":"7"},":newVersion":{"N":"8"}}'

성공하면 명령은 아무것도 출력하지 않고 0으로 종료합니다. 다른 작성자가 먼저 도착했다면 조건이 실패하고 CLI가 서비스 메시지를 보고합니다:

An error occurred (ConditionalCheckFailedException) when calling the UpdateItem operation:
The conditional request failed

설명

  • 성공은 조용합니다. 출력이 없고 종료 코드는 0입니다. 파싱할 것도 단언할 것도 없으므로 셸 스크립트는 종료 상태를 결과로 취급해야 합니다. 갱신된 항목을 출력하고 싶다면 --return-values ALL_NEW를 추가하세요.
  • 실패는 종료 상태 254이며, 이는 CLI v2의 클라이언트 측 오류 코드로 잘못된 형식의 요청과 공유됩니다. 재시도하기 전에 메시지로 분기하세요. 그렇지 않으면 표현식의 오타 하나가 무한 백오프 루프가 됩니다.
  • --return-values-on-condition-check-failure ALL_OLD는 여기서 동작합니다. 유효한 값은 ALL_OLDNONE이며 읽기 용량을 소비하지 않습니다. 오류에서 항목을 꺼내려면 플래그 하나가 더 필요하며, 아래에서 다룹니다.
  • 조건과 업데이트는 별개의 플래그이지만 네임스페이스를 공유합니다. --expression-attribute-names--expression-attribute-values--update-expression--condition-expression에 걸쳐 병합되며, 그래서 생성된 이름이 절마다 다시 시작하지 않고 #upd0, #cond0으로 이어집니다. 하나의 플레이스홀더를 서로 다른 두 의미로 재사용하면 두 번째 것이 조용히 이깁니다.
  • 실패한 쓰기에도 요금이 부과됩니다. 개발자 안내서는 분명합니다. 조건이 false로 평가되어도 쓰기 용량은 소비되며, 이전 항목과 새 항목 중 더 큰 쪽을 기준으로 산정됩니다. 조건은 값싼 존재 여부 탐침이 아닙니다.

실패 출력, 그리고 거기서 항목을 꺼내는 방법

위 코드를 한 번 실행하면 조용히 성공합니다. Version이 더 이상 7이 아닐 때 두 번째로 실행하면 aws-cli/2.36.9가 stderr에 다음을 출력합니다:

aws: [ERROR]: An error occurred (ConditionalCheckFailedException) when calling the UpdateItem operation: The conditional request failed

--return-values-on-condition-check-failure ALL_OLD를 추가하면 기본 출력은 더 있는 것이 있다고 알려주면서도 보여주지는 않습니다:

aws: [ERROR]: An error occurred (ConditionalCheckFailedException) when calling the UpdateItem operation: The conditional request failed

Additional error details:
Item: <complex value>
Use "--cli-error-format json" or another error format to see the full details.

<complex value>가 바로 그 항목이며, 기본 텍스트 렌더러가 감춘 것입니다. --cli-error-format json을 추가하면 전체가 출력됩니다:

{
    "Message": "The conditional request failed",
    "Code": "ConditionalCheckFailedException",
    "Item": {
        "Artist": {"S": "Arturo Sandoval"},
        "Year": {"N": "1994"},
        "Version": {"N": "8"},
        "SongTitle": {"S": "Cubano Chant"},
        "AlbumTitle": {"S": "Danzon"},
        "Genre": {"S": "Latin Jazz"}
    }
}

(속성 맵은 각각 한 줄로 접었고, 나머지는 출력된 그대로입니다.) 첫 번째 실행이 성공했기 때문에 Version은 8이고 Genre가 설정되어 있습니다. 이것이 셸 스크립트에서 닫은 낙관적 잠금 루프입니다. stderr를 jq -r '.Item.Version.N'으로 파이프하고, 그 값을 :expectedVersion으로 되돌려 넣고, 재시도하세요. get-item도 필요 없고, 읽기와 재시도 사이에 세 번째 작성자가 끼어들 틈도 없습니다.

재시도가 공짜는 아닙니다. 거부된 시도마다 쓰기 단위를 소비하므로, 경합하는 키를 빡빡한 루프로 돌리면 아무 진전 없이 계속 요금이 발생합니다. 시도 횟수를 제한하기 전에 재시도 폭풍이 실제로 얼마인지 알고 싶다면, 요금 계산기가 쓰기 속도를 월 금액으로 바꿔 줍니다.

플레이스홀더 맵을 셸에서 따옴표 처리하지 않고 여러분의 테이블에 이런 가드를 실행하려면, DynoTable을 다운로드하세요.

관련 예제

참고 자료

위에 링크된 공식 AWS 문서를 기준으로 2026-07-28에 마지막으로 검증했습니다.

Console 없이 DynamoDB 작업하기

DynamoDB로는 실행할 수 없는 진짜 SQL(JOINs, GROUP BY, 집계)을 실행하는 빠른 DynamoDB 데스크톱 클라이언트. 시각적 편집과 여러분 자신의 Bedrock 키로 동작하는 AI 에이전트를 제공합니다.

30일 무료 체험, 신용카드 불필요 — 이후 기간 제한 없는 무료 요금제.