중급4분 분량

DynamoDB 표현식 속성 이름 및 값

DynamoDB 표현식은 템플릿입니다. 자리 표시자를 작성한 다음 실제 표현식을 제공합니다. 두 개의 측면 지도에 있는 이름과 값. #name은 이름 자리 표시자입니다. :value은 값 자리 표시자입니다. 두 가지를 혼동하면 DynamoDB가 거부합니다. 전체 통화.

DynamoDB에서 #name과 :value의 차이점은 무엇입니까?

#nameExpressionAttributeNames을 통해 제공되는 name 속성에 대한 자리 표시자입니다. :valueExpressionAttributeValues를 통해 제공되는 속성 에 대한 자리 표시자입니다. 예약어, 점 또는 공백을 피하려면 #name를 사용하고 모든 리터럴에 :value를 사용합니다. DynamoDB는 값을 인라인하지 않습니다. 서로 바꿔 사용할 수 없습니다. 그것들을 바꾸면 ValidationException이 나옵니다.

  • #nameExpressionAttributeNames을 통해 속성 이름을 대체합니다. — 사용 속성이 예약어와 충돌하거나 점/공백을 포함할 때마다 발생합니다.
  • :valueExpressionAttributeValues를 통해 값을 대체 — DynamoDB 리터럴을 표현식 텍스트에 인라인하지 않으므로 모든 값은 자리 표시자입니다.
  • 교환이 불가능합니다. :가 속한 #ValidationException, 조용한 무작동이 아닙니다.

SQL에서는 WHERE status = 'published' 두 가지를 모두 인라인합니다. DynamoDB 인라인 둘 다. 그 분열은 모든 신규 이민자를 넘어지게 만드는 것입니다.

두 맵이 존재하는 이유

SQL에서 쿼리 문자열은 열 이름, 리터럴, 연산자 등 모든 것을 전달합니다. DynamoDB는 표현식의 _모양_을 _데이터_에서 의도적으로 분리합니다.

값은 자체 맵에 들어가므로 DynamoDB가 각 값(S, N, BOOL, …)을 입력할 수 있습니다. 따라서 파서는 문자열이 끝나는 위치를 추측할 필요가 없습니다. 또는 잘못되기 위해 탈출합니다. 자세한 내용은 data types in DynamoDB를 참조하세요. 전체 유형 태그 목록.

이름은 다른 이유로 동일하게 처리됩니다. DynamoDB에는 이름이 긴 목록이 있습니다. 예약어 및 이와 일치하는 속성은 그대로 이름으로 표시될 수 없습니다. 표현으로. 자리 표시자는 예약을 완전히 회피합니다.

예약어 트랩

다음은 CMS 기사 테이블입니다 — 파티션 키 BLOG#<blog>, 정렬 키 ARTICLE#<slug> — 속성이 자연스럽게 읽히지만 충돌하는 경우가 있습니다. 예약어:

속성예약된?보유 내용
statusdraft / published
name작성자 표시 이름
size렌더링된 바이트 길이
ttl아카이브 만료(에포크)
slug아니URL 슬러그

status, name, sizettl는 모두 AWS의 예약어 목록에 있으므로 이 첫 번째 단어에서 필터가 실패합니다.

FilterExpression  status = :s

DynamoDB는 ValidationException을 반환합니다. — "속성 이름은 예약되어 있습니다. 키워드; 예약된 키워드: 상태". 수정 사항은 이름 자리 표시자입니다. 절대로 속성 이름 바꾸기:

FilterExpression           #status = :s
ExpressionAttributeNames   { "#status": "status" }
ExpressionAttributeValues  { ":s": { "S": "published" } }

slug은 예약되어 있지 않으므로 slug에 대해 테스트한 쿼리가 작동하고 다음 사람도 그럴 것이라고 가정하십시오. 그러면 status가 그것을 깨뜨립니다. 전체 목록이 이동하므로 외우지 마세요. 모든 이름을 자리 표시자로 지정하면 절대 물릴 일이 없습니다.

항상 모든 값을 매핑합니다.

값은 협상할 수 없습니다. 인라인 리터럴에 대한 구문이 없습니다. 평범한 곳이라도 숫자는 자리 표시자를 얻습니다. 이 업데이트는 기사가 게시되었음을 표시하고 해당 기사에 스탬프를 찍습니다. 크기를 지정하고 30일 아카이브 를 설정합니다.

UpdateExpression:          SET #status = :s, #size = :sz, #ttl = :exp
ExpressionAttributeNames:  { "#status": "status", "#size": "size", "#ttl": "ttl" }
ExpressionAttributeValues: {
  ":s":   { "S": "published" },
  ":sz":  { "N": "20480" },
  ":exp": { "N": "1719792000" }
}

참고 :sz:expN 문자열로 전송됩니다. — DynamoDB의 숫자 유형은 유선입니다. 문자열로 인코딩됩니다. 값 맵은 전체에서 값을 재사용하는 곳이기도 합니다. 조항: :s을 한 번 정의하고 이를 ConditionExpression와 a 모두에서 참조하십시오. FilterExpression.

이 두 지도를 손으로 만드는 것은 오타가 숨어 있는 곳입니다. 는 Expression Builder는 다음 표현식을 생성합니다. 문자열과 두 맵 모두 함께 입력되며, 유형 태그가 채워져 있으므로 자리 표시자는 동기화에서 벗어날 수 없습니다.

아래 빌더는 예약어인 status를 필터링하여 볼 수 있습니다. ExpressionAttributeNames 지도에서 #status로 자동 별칭 지정:

요청 만들기
생성된 코드
new QueryCommand({
  "TableName": "AuditLog",
  "KeyConditionExpression": "#hashKey = :hashKeyValue",
  "FilterExpression": "#filter0 = :filterValue0",
  "ExpressionAttributeNames": {
    "#hashKey": "pk",
    "#filter0": "status"
  },
  "ExpressionAttributeValues": {
    ":hashKeyValue": {
      "S": "TENANT#acme"
    },
    ":filterValue0": {
      "S": "active"
    }
  }
})

중첩되고 어색한 경로의 이름

# 자리 표시자는 예약어를 피하는 것 이상의 역할을 합니다. 문서 경로 구문 사용 점과 괄호, 문자 그대로 점을 포함하는 속성 - 예를 들어 메타데이터 키 og.title — 자리 표시자가 없으면 주소를 지정할 수 없습니다.

ProjectionExpression       #og
ExpressionAttributeNames   { "#og": "og.title" }

이것이 없으면 DynamoDB는 og.title를 "og 맵 내부의 title 필드"로 읽습니다. — 완전히 다른 것입니다. 공백이나 선행 숫자가 있는 이름에 대해서도 마찬가지입니다. 중첩의 경우 각 세그먼트에 자리 표시자를 지정합니다. #meta.#author#meta#author가 정의되었습니다.

이름과 값을 나란히 비교

#name:value
대체품속성 이름속성
지도ExpressionAttributeNamesExpressionAttributeValues
접두사#:
필요한예약어, 점, 공백항상 — 인라인 리터럴 없음
잘못된 오류ValidationExceptionValidationException

값이 이름으로 입력되면 DynamoDB는 다음과 같은 속성을 찾습니다. published 그리고 귀하의 조건은 귀하가 의도한 것과 결코 일치하지 않을 것입니다. 따라서 API 대신 크게 실패합니다. 그 엄격함이 특징입니다. 조용한 오답은 없습니다.

함정과 다음 단계

  • 사용하지 않는 자리 표시자 선언 — DynamoDB는 지도든. 표현식보다 앞서가 아니라 표현식에서 맵을 작성하십시오.
  • 표현식 편집 후 :v 재사용 — 절을 삭제하면 해당 값이 지연되어 사용되지 않은 항목 오류가 발생합니다. 건축업자는 그것들을 고정 상태로 유지합니다.
  • 이름은 한 번 작동했기 때문에 안전하다고 가정 — 예약어 충돌은 속성별. 자리 표시자를 균일하게 지정하고 추측을 중지합니다.

이러한 맵은 모든 쓰기 경로에 표시되므로 자연스럽게 다음과 쌍을 이룹니다. single-table design 그리고 알면서 when to Query vs Scan 필터를 부착하기 전에.

표현식과 두 맵을 모두 생성합니다. Expression Builder, 그럼 try DynoTable 자신의 테이블에 놓고 그 결과를 지켜보세요. 자리 표시자가 해결됩니다.

업데이트됨