Python(boto3)의 DynamoDB GetItem

get_item전체 기본 키로 항목 하나를 가져옵니다. boto3의 저수준 클라이언트(boto3.client("dynamodb"))는 양방향으로 DynamoDB JSON을 말하므로, 키는 타입에 감싸인 채로 들어가고 항목도 같은 형태로 돌아옵니다. query, scan과 어떻게 다른지는 항목 기반 작업에서 다룹니다.

코드

import boto3

client = boto3.client("dynamodb")

response = client.get_item(
    TableName="Music",
    Key={"Artist": {"S": "Arturo Sandoval"}, "SongTitle": {"S": "Cubano Chant"}},
    ProjectionExpression="#proj0, #proj1, #proj2, #proj3",
    ExpressionAttributeNames={"#proj0": "Artist", "#proj1": "SongTitle", "#proj2": "AlbumTitle", "#proj3": "Year"},
)

item = response.get("Item")
if item is None:
    print("Item not found")
else:
    print(item)

설명

찾지 못하면 Item 키 자체가 없는 응답이 돌아옵니다. None도 아니고 빈 딕셔너리도 아닙니다. 같은 테이블에서 존재하지 않는 키를 읽었을 때, 응답의 최상위 키는 정확히 다음과 같았습니다:

['ResponseMetadata']

그래서 위 코드가 response.get("Item")을 씁니다. response["Item"]은 평범한 미발견 경로에서 KeyError를 일으키며, 이것이 없는 행 하나가 웹 핸들러에서 500으로 변하는 경로입니다. 읽기에 대한 과금은 그대로입니다. AWS의 읽기 용량 문서는 "if you perform a read operation on an item that doesn't exist, DynamoDB will still consume read throughput as outlined above"라고 밝힙니다(2026-07-28 확인).

Year는 예약어이며, 그래서 생성된 코드가 투영하는 모든 속성에 별칭을 붙입니다. #proj 별칭을 빼고 ProjectionExpression="Year"를 넘기면 엔진이 읽기를 거부합니다:

ValidationException: Invalid ProjectionExpression: Attribute name is a reserved keyword; reserved keyword: Year

무조건 별칭을 붙이는 데는 비용이 들지 않으면서 이 실패 부류 전체가 사라집니다. 전체 목록은 573단어이며, "Attribute name is a reserved keyword"를 참고하세요.

Key를 틀리는 방법 네 가지, 서로 다른 메시지 세 가지. 이들을 구분해 둘 값어치가 있습니다. 어느 것도 사람들이 예상하는 "provided key element does not match the schema" 오류가 아니기 때문입니다. Artist(파티션) + SongTitle(정렬)로 키가 잡힌 Music 테이블에 대해 재현했습니다:

넘긴 값그대로 옮긴 ValidationException 메시지
{"Artist": …} — 정렬 키 누락The number of conditions on the keys is invalid
{"Artist": …, "SongTitle": …, "Extra": …}The number of conditions on the keys is invalid
{"Artist": …, "Song": …} — 잘못된 속성 이름One of the required keys was not given a value
{"Artist": {"N": "1"}, …} — 잘못된 타입One or more parameter values were invalid: Type mismatch for key

키 속성이 빠진 경우와 더 들어간 경우가 같은 메시지를 내놓는다는 점에 주목하세요. 즉 "number of conditions"는 "너무 적게 넘겼다"가 아니라 "키 스키마를 정확히 그대로 건네지 않았다"는 뜻입니다.

ProjectionExpression은 페이로드를 줄이지 청구서를 줄이지 않습니다. 약 15 KB짜리 항목을 ReturnConsumedCapacity="TOTAL"로 세 가지 방식으로 읽으면:

full item, eventually consistent          CapacityUnits: 2.0
ProjectionExpression="#y" (Year only)     CapacityUnits: 2.0
ProjectionExpression="#y" + ConsistentRead  CapacityUnits: 4.0

투영은 응답을 약 15 KB에서 숫자 하나로 바꿨지만 비용은 하나도 바꾸지 못했습니다. AWS는 이를 분명히 말합니다: "The number of capacity units consumed will be the same whether you request all of the attributes (the default behavior) or just some of them (using a projection expression)"(Query API Reference, 2026-07-28 확인). 그 목록에서 숫자를 움직이는 유일한 플래그는 ConsistentRead=True이며, 값을 두 배로 만듭니다. 투영이 실제로 무엇을 위한 것인지는 투영 표현식을 참고하세요.

리소스 API는 더 예쁜 표기가 아니라 다른 계약입니다. boto3.resource("dynamodb").Table("Music").get_item(...)은 평범한 Python을 반환하며 모든 숫자를 decimal.Decimal로 돌려줍니다:

{'Artist': 'Arturo Sandoval', 'AlbumTitle': 'Danzon', 'Awards': Decimal('0'), 'Year': Decimal('1994'), 'SongTitle': 'Cubano Chant'}

이는 양날의 검입니다. 같은 API로 float을 써서 되쓰면 요청이 기기를 떠나기도 전에 예외가 발생합니다:

TypeError: Float types are not supported. Use Decimal types instead.

이 문제에 부딪혔다면 "Float types are not supported"에 해결책이 있습니다. 진짜 함정은 한 코드베이스에서 두 API를 섞는 것입니다. 저수준 클라이언트는 리소스 API였다면 거부했을 {"N": "1.5"}도 군말 없이 받아들입니다.

오류는 botocore 예외로 도착하며, boto3는 그것들에 실제 클래스를 부여합니다. 1.43.58에서 조건 실패 시 발생하는 객체는 ClientError의 하위 클래스인 ConditionalCheckFailedException이므로, except ClientErrorerr.response["Error"]["Code"] 검사를 더한 방식과 except client.exceptions.ConditionalCheckFailedException 방식 모두 동작합니다. 코드베이스가 이미 쓰는 쪽을 택하세요. str(e)로 매칭하지는 마세요.

시각적으로 해보기

손으로 별칭을 붙이기 전에: 무료 DynamoDB 예약어 검사기가 속성 이름을 받아 573개 예약어 중 어느 것에 걸렸는지 알려 주고, 붙여 넣을 수 있는 ExpressionAttributeNames 맵을 내놓습니다.

테이블을 탐색하고 자신의 데이터에 GetItem을 실행하려면 — 키 폼, 결과 그리드, 요청을 boto3 코드로 다시 복사하기까지 — DynoTable을 다운로드하세요.

관련 가이드

참고 자료

2026-07-28에 boto3 1.43.58 / botocore 1.43.58으로 포트 9000의 DynamoDB Local(amazon/dynamodb-local)에 대해 재현했습니다. 위의 모든 메시지와 용량 수치는 엔진 출력을 그대로 옮긴 것입니다. DynamoDB Local은 실제 서비스가 아니며, 둘이 오류 문구를 다르게 쓴다고 알려진 경우에는 해당 오류 페이지에 그 사실을 적어 둡니다.

Console 없이 DynamoDB 작업하기

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

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