【Python】CDKでGSIを設定したDynamoDBのテーブルを作る
AWS CDK で GSI(グローバルセカンダリインデックス)を持った DynamoDB のテーブルを作成し、AWS CLI で GSI にクエリを投げます 😊
今回の構成はこんな感じです 👍
プロジェクションタイプは追加設定が必要なINCLUDE
でやってみようと思います。
前提
cdk のシリーズの続き。
プロジェクションの設定はこのあたり、
https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Projection.html
では 作っていきましょう 👻
requirements.txt
DynamoDB のみです 👍
aws-cdk.core==1.72.0
aws-cdk.aws_dynamodb==1.72.0
スタックファイル
メインはここですが、サンプルコードがあれば説明不要かなと思います 😅
ざっくりやってることはテーブルを新規に作り、GSI を追加してます。
追加した GSI は Index 名がHogeGSI
で、テーブルとは異なるプライマリーキーgsi_pk, gsi_sk
を持ち、
projection_param_a, projection_param_b
がプロジェクションされる設定です 👍
from aws_cdk import core
from aws_cdk.aws_dynamodb import Attribute, AttributeType, ProjectionType, Table
class DynamoTableGsiStack(core.Stack):
def __init__(self, scope: core.Construct, id: str, **kwargs) -> None:
super().__init__(scope, id, **kwargs)
table = Table(
self,
"DynamoTableGsiTable",
partition_key=Attribute(name="pk", type=AttributeType.NUMBER),
sort_key=Attribute(name="sk", type=AttributeType.STRING),
)
table.add_global_secondary_index(
index_name="HogeGSI",
partition_key=Attribute(name="gsi_pk", type=AttributeType.NUMBER),
sort_key=Attribute(name="gsi_sk", type=AttributeType.STRING),
projection_type=ProjectionType.INCLUDE,
non_key_attributes=["projection_param_a", "projection_param_b"], # INCLUDEでプロジェクションするアトリビュート
)
エントリーポイントへ追記
下記を追加
...
from stacks.dynamo_table_gsi_stack import DynamoTableGsiStack
...
DynamoTableGsiStack(app, "dynamo-table-gsi-stack", env=env)
...
デプロイ
$ cdk deploy dynamo-table-gsi-stack
動作確認
作ったテーブルの名前を取得します。
$ aws dynamodb list-tables | grep dynamo-table-gsi-stack
今回はこんな(↓)名前でした。
dynamo-table-gsi-stack-DynamoTableGsiTable3CEEAFD7-ZBM15Z9CA40P
テーブルの詳細を確認して GSI が作られていることを確認します
ちょっと長いですね 😅
$ TABLE_NAME=dynamo-table-gsi-stack-DynamoTableGsiTable3CEEAFD7-ZBM15Z9CA40P
$ aws dynamodb describe-table --table-name $TABLE_NAME
{
"Table": {
"AttributeDefinitions": [
{
"AttributeName": "gsi_pk",
"AttributeType": "N"
},
{
"AttributeName": "gsi_sk",
"AttributeType": "S"
},
{
"AttributeName": "pk",
"AttributeType": "N"
},
{
"AttributeName": "sk",
"AttributeType": "S"
}
],
"TableName": "dynamo-table-gsi-stack-DynamoTableGsiTable3CEEAFD7-ZBM15Z9CA40P",
"KeySchema": [
{
"AttributeName": "pk",
"KeyType": "HASH"
},
{
"AttributeName": "sk",
"KeyType": "RANGE"
}
],
"TableStatus": "ACTIVE",
"CreationDateTime": xxxxxxxxxx.xxx,
"ProvisionedThroughput": {
"NumberOfDecreasesToday": 0,
"ReadCapacityUnits": 5,
"WriteCapacityUnits": 5
},
"TableSizeBytes": 0,
"ItemCount": 0,
"TableArn": "arn:aws:dynamodb:xxxxxxxxxxxxxx:xxxxxxxxxxxx:table/dynamo-table-gsi-stack-DynamoTableGsiTable3CEEAFD7-ZBM15Z9CA40P",
"TableId": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"GlobalSecondaryIndexes": [
{
"IndexName": "HogeGSI",
"KeySchema": [
{
"AttributeName": "gsi_pk",
"KeyType": "HASH"
},
{
"AttributeName": "gsi_sk",
"KeyType": "RANGE"
}
],
"Projection": {
"ProjectionType": "INCLUDE",
"NonKeyAttributes": [
"projection_param_b",
"projection_param_a"
]
},
"IndexStatus": "ACTIVE",
"ProvisionedThroughput": {
"NumberOfDecreasesToday": 0,
"ReadCapacityUnits": 5,
"WriteCapacityUnits": 5
},
"IndexSizeBytes": 0,
"ItemCount": 0,
"IndexArn": "arn:aws:dynamodb:xxxxxxxxxxxxxx:xxxxxxxxxxxx:table/dynamo-table-gsi-stack-DynamoTableGsiTable3CEEAFD7-ZBM15Z9CA40P/index/HogeGSI"
}
]
}
}
ちゃんと設定された、、、ようですが、一応動きを確認しておきましょうか(笑)
# ダミーのデータを入れてみる
$ aws dynamodb put-item \
--table-name $TABLE_NAME \
--item '{"pk":{"N":"1234"},"sk":{"S":"hogehoge"},"gsi_pk":{"N":"987"},"gsi_sk":{"S":"hugohugo"},"projection_param_a":{"S":"HOGEHOGE"},"projection_param_b":{"S":"HUGOHUGO"},"dummy_param":{"S":"このアトリビュートはGSIでは取得されない"}}'
# テーブルにquery
$ aws dynamodb query \
--table-name $TABLE_NAME \
--key-condition-expression "pk =:v1" \
--expression-attribute-values '{":v1":{"N":"1234"}}'
{
"Items": [
{
"gsi_pk": {
"N": "987"
},
"gsi_sk": {
"S": "hugohugo"
},
"projection_param_b": {
"S": "HUGOHUGO"
},
"projection_param_a": {
"S": "HOGEHOGE"
},
"dummy_param": {
"S": "このアトリビュートはGSIでは取得されない"
},
"sk": {
"S": "hogehoge"
},
"pk": {
"N": "1234"
}
}
],
"Count": 1,
"ScannedCount": 1,
"ConsumedCapacity": null
}
# Indexにquery
$ aws dynamodb query \
--table-name $TABLE_NAME \
--index-name HogeGSI \
--key-condition-expression "gsi_pk =:v1" \
--expression-attribute-values '{":v1":{"N":"987"}}'
{
"Items": [
{
"gsi_pk": {
"N": "987"
},
"sk": {
"S": "hogehoge"
},
"pk": {
"N": "1234"
},
"gsi_sk": {
"S": "hugohugo"
},
"projection_param_b": {
"S": "HUGOHUGO"
},
"projection_param_a": {
"S": "HOGEHOGE"
}
}
],
"Count": 1,
"ScannedCount": 1,
"ConsumedCapacity": null
}
テーブルにも GSI にも query が通ることが確認できました 👍
プロジェクションした param も取得できてます。
デストロイ
$ cdk destroy dynamo-table-gsi-stack
まとめ
CDK で GSI を持った Dynamo のテーブルを作り、cli 経由で query を投げて動作確認をしました 👍