DynamoDB expression attribute name에 . 문자가 포함되는 경우의 처리

Wonwoo Seo·2024년 1월 4일

DynamoDB expression attribute name에서 . 문자는 경로 내의 구분자(중첩 속성)로 사용되는 특수 문자이다.

Expression name 관련 AWS Documentation

Name

위 문서에서 중첩 속성(Nested Attributes) 섹션의 예제를 AWS SDK Go v2의 DynamoDB expression 패키지를 이용해 아래와 같이 작성해 보았다.

key := expression.Key("Id").Equal(expression.Value(123))
proj := expression.NamesList(expression.Name("ProductReviews.OneStar"))
expr, err := expression.NewBuilder().WithKeyCondition(key).WithProjection(proj).Build()
if err != nil {
	return err
}

여기서 expr의 KeyCond, Projection, Names를 출력해보면

fmt.Println(*expr.KeyCondition) // #0 = :0
fmt.Println(*expr.Projection()) // #1.#2
fmt.Println(expr.Names()) // map[#0:Id #1:ProductReviews #2:OneStar]

자동으로 문서에서 제시한 접근법과 동일한 형식으로 표현식이 생성된 것을 볼 수 있다.

NameNoDotSplit

만약 ProductReviews.OneStar가 중첩 속성이 아니라 일반 속성이고, 의도적으로 .을 포함해 이름을 정한 경우라면 어떻게 해야 할까?

expression.Name 의 구현을 들여다보면 인수로 받은 문자열을 무조건 .을 기준으로 split하는 것을 볼 수 있다.
대신 이번 경우처럼 속성 이름 내에 .을 유지해야 한다면 expression.NameNoDotSplit 을 사용해야 한다!

proj := expression.NamesList(expression.NameNoDotSplit("ProductReviews.OneStar"))
fmt.Println(*expr.Projection()) // #1
fmt.Println(expr.Names()) // map[#0:Id #1:ProductReviews.OneStar]

AppendName

그렇다면 이제 문서의 구조가 아래와 같다고 할 때,

{
	"Id": "123",
	"Attributes": {
		"ProductReviews.OneStar": ["review_id"]
	}
}

ProductReviews.OneStar 속성에 접근하려면 어떻게 해야 할까?

Attributes.ProductReviews.OneStar 경로를 Attributes와 ProductReviews.OneStar로 나누어서 expression을 만들어야 하는데, 위에 소개한 방법만으로는 접근이 되질 않는다.

  • expression.Name을 사용한 경우:

    proj := expression.NamesList(expression.Name("Attributes.ProductReviews.OneStar"))
    fmt.Println(*expr.Projection()) // #1.#2.#3
    fmt.Println(expr.Names()) // map[#0:Id #1:Attributes #2:ProductReviews #3:OneStar]
  • expression.NameNoDotSplit을 사용한 경우:

    proj := expression.NamesList(expression.NameNoDotSplit("Attributes.ProductReviews.OneStar"))
    fmt.Println(*expr.Projection()) // #1
    fmt.Println(expr.Names()) // map[#0:Id #1:Attributes.ProductReviews.OneStar]

이런 경우에는 (expression.NameBuilder).AppendName을 사용해 위의 두 방법들을 조합할 수 있다!

proj := expression.NamesList(expression.Name("Attributes").AppendName(expression.NameNoDotSplit("ProductReviews.OneStar")))
fmt.Println(*expr.Projection()) // #1.#2
fmt.Println(expr.Names()) // map[#0:Id #1:Attributes #2:ProductReviews.OneStar]

결론

. 문자 외의 다른 특수 문자에도 사용이 가능할 것이다.
expression.NameNoDotSplit과 expression.AppendName의 이용법이 잘 설명된 곳을 찾을 수 없어서 짧게 정리해 보았다.

참고

https://github.com/aws/aws-sdk-go/issues/2570
https://github.com/aws/aws-sdk-go-v2/pull/1590

이용한 패키지 버전

github.com/aws/aws-sdk-go-v2/feature/dynamodb/expression v1.6.12

profile
Blockchain / Backend Developer

0개의 댓글