ここでは、Node.js 用の AWS SDK ver.2 を使って Amazon DynamoDB を操作する方法を説明します。
TypeScript の基本的な環境構築 は終わっているものとします。
SDK ver.3 を使う方法はこちらの記事 を参照してください。
基本的には ver.3 の使用が推奨されていますが、AWS の Lambda 実行環境は現時点(2021年5月)でも ver.2 がインストールされていたりするので、ver.2 の需要はまだあると思います。
Dynamo DB 用の SDK (ver.2) をインストールする
AWS SDK version 2 で DynamoDB を扱うには、次のように AWS SDK パッケージ全体をインストールする必要があります(version 3 では DynamoDB サービスなどのパッケージを個別にインストールできます)。
これで、TypeScript コードから次のように SDK モジュールをインポートできるようになります。
AWS.DynamoDB
だけ参照したければ、次のようにインポートできます。
DynamoDB インスタンスの生成
基本
DynamoDB の API を呼び出すには、まずは AWS.DynamoDB インスタンスを生成する必要があります。
接続設定 (config)
DynamoDB コンストランクタ の引数でオプションオブジェクトを渡すと、接続先のリージョンやエンドポイントを設定することができます。
例えば、エンドポイントを http://localhost:8000
に設定すれば、DynamoDB Local によるテスト用サーバに接続できます。
認証情報ファイルなど で実行ユーザーに適切な接続情報が設定されていれば、上記のようにコード内で接続設定する必要はありませんが、少なくとも apiVersion
は明示しておくとが推奨されています。
環境変数(AWS_REGION
、AWS_ACCESS_KEY_ID
、AWS_SECRET_ACCESS_KEY
など)で接続情報を設定することもできます。
接続情報の優先順位は次の通りです。
- プログラム内での設定(ローカル設定 > グローバル設定)
- 環境変数での設定 (
AWS_REGION
, AWS_ACCESS_KEY_ID
, AWS_SECRET_ACCESS_KEY
, AWS_SESSION_TOKEN
) - 認証情報ファイルでの設定 (
~/.aws/credentials
, ~/.aws/config
)
SDK 全体のグローバル設定を変更する場合は、AWS.config.update
メソッドに AWS.Config オブジェクトを渡します。
このグローバル設定は、これ以降に生成されるクライアントオブジェクトのデフォルト設定として使用されます。
プロキシ設定
社内のプロキシ環境などから接続するときは、AWS.Config
の httpOptions
プロパティを使用します。
DynamoDB.DocumentClient インスタンス
AWS.DynamoDB
インスタンスの代わりに、AWS.DynamoDB.DocumentClient
インスタンスを使うと、もう少し抽象度の高い API で CRUD 系操作を行えるようです。
用途によってはこちらを使った方が楽かもしれませんが、createTable
などテーブル自体の操作はできません。
インスタンスの作成方法は AWS.DynamoDB
と同様です。
テーブルを作成する (createTable)
テーブルを削除する (deleteTable)
テーブルの一覧を取得する (listTables)
テーブルの詳細情報を取得する (describeTable)
指定したテーブルのスキーマ情報などを取得できます。
アイテムを追加する (putItem)
DynamoDB を使う場合
putItem
メソッドでテーブルに要素を追加するときは、少なくともプライマリキー属性(パーティションキー、およびソートキー)の指定が必要です(Games
テーブルの例では Hardware
と GameId
)。
すでに同じキーの要素が存在する場合、デフォルトでは新しい値で上書きされます。
ReturnValues
プロパティに ALL_OLD
を指定しておくと、もともと格納されていた値を戻り値として取得できます。
putItem
メソッドはデフォルトではアイテムの内容を上書きしますが、この振る舞いを抑制したいときは、コマンドのパラメータに次のように ConditionExpression
を指定します。
このようにすると、プライマリキーが一致するアイテムがすでに存在する場合に、ConditionalCheckFailedException
例外が発生するようになります。
DynamoDB.DocumentClient を使う場合
DocumentClient
インスタンスを使用すると、属性値の指定が若干シンプルになります(S
や N
などのタイプ指定が必要なくなります)。
それ以外は同じです。
実行結果の形式も少しだけシンプルになります。
アイテムの属性値を部分的に更新する (updateItem)
DynamoDB を使う場合
putItem
に似たメソッドに updateItem
があります。
putItem
はプライマリーキー属性が一致するアイテムがあると、その内容を完全に置き換えますが、updateItem
の場合は、指定した属性の値のみを更新 します(まだ存在しない属性を指定すると追加されます)。
プライマリーキー属性に一致するアイテムが見つからない場合に、新しいアイテムを追加するのは putItem
も updateItem
も同様です。
属性値の更新内容は、SQL のプレースホルダーを使った構文のような感じで指定する必要があります。
DynamoDB の API は複雑すぎるとは聞いていましたが、確かにこの API 仕様はクレイジーですね・・・(AWS SDK が低レベルすぎるだけかもしれませんが)。
次の例では、既存のアイテムの Title
属性の値を更新し、さらに新しい属性 Maker
を追加しています。
新しい属性名は #xxx
、新しい属性値は :xxx
といった形のプレースホルダーで指定する必要があります。
DynamoDB.DocumentClient を使う場合
DocumentClient
インスタンスを使用すると、属性値の指定が若干シンプルになります(S
や N
などのタイプ指定が必要なくなります)。
それ以外は同じです。
実行結果の形式も少しだけシンプルになります。
アイテムを取得する (getItem)
DynamoDB を使う場合
アイテムを 1 つ取得するときは、テーブル名 (Table
) と、アイテムを特定するためのプライマリーキー (Key
) を指定します。
複合プライマリキーを使用している場合は、パーティションキーとソートキーの両方を指定する必要があります(ValidationException
が発生します)。
DynamoDB.DocumentClient を使う場合
DocumentClient
インスタンスを使用すると、プライマリーキーの指定が若干シンプルになります(S
や N
などのタイプ指定が必要なくなります)。
それ以外は同じです。
実行結果の形式も少しだけシンプルになります。
アイテムを削除する (deleteItem)
DynamoDB を使う場合
アイテムを削除するときは、テーブル名 (Table
) と、アイテムを特定するためのプライマリーキー (Key
) を指定します。
複合プライマリキーを使用している場合は、パーティションキーとソートキーの両方を指定する必要があります(ValidationException
が発生します)。
DynamoDB.DocumentClient を使う場合
DocumentClient
インスタンスを使用すると、プライマリーキーの指定が若干シンプルになります(S
や N
などのタイプ指定が必要なくなります)。
それ以外は同じです。
実行結果の形式も少しだけシンプルになります。
バッチ処理 - 複数のアイテムを追加・削除する (batchWriteItem)
DynamoDB テーブルに複数のアイテムを追加、削除したいときは、putItem
や deleteItem
を何度も呼び出すよりも、batchWriteItem
を使うのが効率的です。
ただし、最大でも 25 項目までといった細かな制約があります。
その他の制約などは、BatchWriteItem の仕様 を確認してください。
次の例では、Games
テーブルに 2 つの項目を追加し、1 つの項目を削除しています。
DynamoDB を使う場合
DynamoDB.DocumentClient を使う場合
DocumentClient
インスタンスを使用すると、属性値の指定が若干シンプルになります(S
や N
などのタイプ指定が必要なくなります)。
それ以外は同じです。
batchWrite のパラメーターを作るユーティリティ関数を作る
DynamoDB.DocumentClient.batchWrite
メソッドに渡すパラメーターをハードコードするのは大変なので、現実的には、複数アイテムをまとめて追加するためのラッパー関数的なものを用意することになると思います。
テーブル内の要素をすべて取得する (scan)
DynamoDB テーブル内のすべてのアイテムを取得するには scan
メソッドを使用します。
フィルタ条件を指定することもできますが、内部的には「全アイテムの取得 → フィルタ」という動作になるため、scan
メソッドは基本的にはアイテム数が少ない場合にのみ使用できます(返却するデータは 1MB までなどの制約があります)。
プライマリーキーで検索条件を指定できる場合は、scan
ではなく query
メソッドを使うことで効率的な取得が可能です。
DynamoDB
クラスにも DynamoDB.DocumentClient
クラスにも同名の scan
メソッドがありますが、後者の方が若干シンプルに記述できる(S
や N
などの属性タイプ指定を省略できる)ので、そちらを使ったサンプルコードを示します。
scan
結果を何らかの条件で絞り込みたい場合は、FilterExpression
パラメーターを使用します。
次の例では、Genre
属性が ACT
のアイテムだけを取得しています。
ただし前述のように、FilterExpression
による絞り込みは、全アイテム取得後にフィルターしているだけなので注意してください(アイテム数が増えてくると機能しなくなります)。
テーブル内の要素をプライマリーキーでフィルタして取得する (query)
DynamoDB テーブルから、指定したプライマリーキーに一致するアイテムを検索するには、query
メソッドを使用します。
主に、複合キー(パーティションキー + ソートキー)で構成されているテーブルから、
- パーティションキーのみの指定
- パーティションキー + ソートキーの条件指定
といった検索を行います。
ソートキーの方は部分一致や大小比較など、ある程度柔軟なフィルタ条件を指定できますが、パーティションキーの方は、あくまで完全一致させる必要があります。
関連記事