DynamoDB の GSI のレンジキーの値を定義時とは違う型で put-item できないことを確認する
Summary
- DynamoDB のテーブルに GSI を定義するときは、AttributeDefinitions でハッシュキーやレンジキーの名前と型を定義することになる
- GSI を定義したあと、その型と違うデータ型としてput-itemはできない
- 例えば、DynamoDB の GSI のレンジキーを文字列としたとき、NULL型(
"filed-name": {"NULL": true }など)として更新(put-item)はできない。- カラム自体を定義しなければ、更新可能
再現手順
DynamoDB で、テーブルを作成し、いくつかデータを登録したあと、GSIを追加して、再度同じようなデータを作成し、結果を確認する。
テーブルを作成する
aws dynamodb create-table \
--table-name Members \
--attribute-definitions \
AttributeName=id,AttributeType=S \
--key-schema AttributeName=id,KeyType=HASH \
--billing-mode PAY_PER_REQUEST
{
"TableDescription": {
"AttributeDefinitions": [
{
"AttributeName": "id",
"AttributeType": "S"
}
],
"TableName": "Members",
"KeySchema": [
{
"AttributeName": "id",
"KeyType": "HASH"
}
],
"TableStatus": "CREATING",
"CreationDateTime": 1571288732.889,
"ProvisionedThroughput": {
"NumberOfDecreasesToday": 0,
"ReadCapacityUnits": 0,
"WriteCapacityUnits": 0
},
"TableSizeBytes": 0,
"ItemCount": 0,
"TableArn": "arn:aws:dynamodb:***:***:table/Members",
"TableId": "692f8720-***",
"BillingModeSummary": {
"BillingMode": "PAY_PER_REQUEST"
}
}
}
データを作成する
# A: locationあり
aws dynamodb put-item \
--table-name Members \
--item \
"{\"id\": {\"S\": \"a\"}, \"name\": {\"S\": \"takada\"}, \"group_id\": {\"S\": \"100\"}, \"location\": {\"S\": \"Tokyo\"}}"
# B: locationあり2
aws dynamodb put-item \
--table-name Members \
--item \
"{\"id\": {\"S\": \"b\"}, \"name\": {\"S\": \"takada\"}, \"group_id\": {\"S\": \"100\"}, \"location\": {\"S\": \"Toyama\"}}"
# C: location null型
aws dynamodb put-item \
--table-name Members \
--item \
"{\"id\": {\"S\": \"c\"}, \"name\": {\"S\": \"takada\"}, \"group_id\": {\"S\": \"100\"}, \"location\": {\"NULL\": true }}"
# D: location のカラム自体がない
aws dynamodb put-item \
--table-name Members \
--item \
"{\"id\": {\"S\": \"d\"}, \"name\": {\"S\": \"takada\"}, \"group_id\": {\"S\": \"100\"}}"
A ~ D のput-itemに成功する。
GSIを作成する
# group_id, location で GSI作成
aws dynamodb update-table \
--table-name Members \
--billing-mode PAY_PER_REQUEST \
--attribute-definitions \
"[{ \"AttributeName\": \"id\", \"AttributeType\": \"S\" }, { \"AttributeName\": \"group_id\", \"AttributeType\": \"S\" }, { \"AttributeName\": \"location\", \"AttributeType\": \"S\" }]" \
--global-secondary-index-updates \
"[{ \"Create\": { \"IndexName\": \"group_id-location\", \"KeySchema\": [ { \"AttributeName\": \"group_id\", \"KeyType\": \"HASH\" }, { \"AttributeName\": \"location\", \"KeyType\": \"RANGE\" } ], \"Projection\": { \"ProjectionType\": \"ALL\" } } }]"
作成したGSIでqueryする
インデックスが完了してからqueryする
# Query
aws dynamodb query \
--table-name Members \
--index-name group_id-location \
--key-condition-expression 'group_id = :group_id' \
--expression-attribute-value "{\":group_id\": {\"S\": \"100\"}}"
↓「C: location null」と「D: location のカラム自体がない」はヒットしない
{
"Items": [
{
"location": {
"S": "Tokyo"
},
"id": {
"S": "a"
},
"name": {
"S": "takada"
},
"group_id": {
"S": "100"
}
},
{
"location": {
"S": "Toyama"
},
"id": {
"S": "b"
},
"name": {
"S": "takada"
},
"group_id": {
"S": "100"
}
}
],
"Count": 2,
"ScannedCount": 2,
"ConsumedCapacity": null
}
再度同じパターンのデータを作成する
# E: locationあり
aws dynamodb put-item \
--table-name Members \
--item \
"{\"id\": {\"S\": \"e\"}, \"name\": {\"S\": \"takada\"}, \"group_id\": {\"S\": \"100\"}, \"location\": {\"S\": \"Tokyo\"}}"
# F: locationあり2
aws dynamodb put-item \
--table-name Members \
--item \
"{\"id\": {\"S\": \"f\"}, \"name\": {\"S\": \"takada\"}, \"group_id\": {\"S\": \"100\"}, \"location\": {\"S\": \"Toyama\"}}"
↓「G: location null」のパターンでは、エラーが発生し put-item はできない。Type mismatch for Index Key location Expected: S Actual: NULL とエラーが発生する。
# G: location null型
aws dynamodb put-item \
--table-name Members \
--item \
"{\"id\": {\"S\": \"g\"}, \"name\": {\"S\": \"takada\"}, \"group_id\": {\"S\": \"100\"}, \"location\": {\"NULL\": true }}"
An error occurred (ValidationException) when calling the PutItem operation: One or more parameter values were invalid: Type mismatch for Index Key location Expected: S Actual: NULL IndexName: group_id-location
↓「H: location のカラム自体がない」のパターンでは、put-itemが成功する
# H: location のカラム自体がない
aws dynamodb put-item \
--table-name Members \
--item \
"{\"id\": {\"S\": \"h\"}, \"name\": {\"S\": \"takada\"}, \"group_id\": {\"S\": \"100\"}}"
再度queryする
# Query
aws dynamodb query \
--table-name Members \
--index-name group_id-location \
--key-condition-expression 'group_id = :group_id' \
--expression-attribute-value "{\":group_id\": {\"S\": \"100\"}}"
↓locationの値が設定されたデータA,B,E,Fがヒットする
{
"Items": [
{
"location": {
"S": "Tokyo"
},
"id": {
"S": "e"
},
"name": {
"S": "takada"
},
"group_id": {
"S": "100"
}
},
{
"location": {
"S": "Tokyo"
},
"id": {
"S": "a"
},
"name": {
"S": "takada"
},
"group_id": {
"S": "100"
}
},
{
"location": {
"S": "Toyama"
},
"id": {
"S": "f"
},
"name": {
"S": "takada"
},
"group_id": {
"S": "100"
}
},
{
"location": {
"S": "Toyama"
},
"id": {
"S": "b"
},
"name": {
"S": "takada"
},
"group_id": {
"S": "100"
}
}
],
"Count": 4,
"ScannedCount": 4,
"ConsumedCapacity": null
}