読者です 読者をやめる 読者になる 読者になる

銀の弾丸

プログラミングに関して、いろいろ書き残していければと思っております。

DynamoDB:条件式のプレースホルダを自動生成してみましょう

DynamoDBから条件付きでQueryやScanを行う場合、条件式の中で使われているキーワード(予約語)をプレースホルダーに変換しなければならなくて面倒ですよね。

プレースホルダーには2種類あって(属性名のプレースホルダーと値のプレースホルダー)別の対応をしなければなりません。さらにキーワードの数がかなり多くて。さらにさらに、なんとも一般的な単語がたくさん・・・。

てなことで、怒りに任せて、条件式をテーブルの属性名や値をそのまま使って記述してDynamoDBからクエリできるnode.jsのコマンド群をご紹介。DynamoDB関係以外のコマンドセットも含まれています(Lambda, API Gateway, IoT, IAM等)。

コンソールからデータの有無や内容を、軽く確認する時に、ちょっと便利です。

また、npm aws-node-utilで公開しているnodeモジュールなので、プレースホルダーに変換する部分を独自のプログラムから利用可能と思われます(ちゃんと確認していませんが・・・)

npmは以下↓からどうぞ。

www.npmjs.com

ご本尊はGitHubにあります。ご意見・ご要望などあればIssueでよろしく。

github.com


f:id:takamints:20160604133023p:plain



DynamoDBのプレースホルダを気にせず使える3つのコマンド

  1. aws-dynamodb-put-item - 項目の追加と更新
  2. aws-dynamodb-query - 項目のクエリ
  3. aws-dynamodb-scan - 項目のスキャン

AWS CLIのデフォルトユーザー、デフォルトリージョンで接続します。

セットアップ

npmでグローバルにインストールしてください。

$ npm install aws-node-util --global

1. aws-dynamodb-putItem - 項目追加・更新

テーブルに項目を追加、または更新します。item-expressionで指定したキーがすでにあるなら上書きされ、なければ追加されます。

aws-dynamodb-put-item [options] <tableName> <item-expression>

パラメータ

  • tableName - 操作対象のテーブル名

  • item-expression - 追加・更新する項目を属性名=属性値,属性名=属性値という形式で記述します。

項目には、少なくともテーブルの全てのキー属性が含まれていなくてはなりません。キーの値によって項目が追加されるか更新されるかが決まるからです。これはDynamoDBの仕様です。

属性名と属性値のプレースホルダーは自動的に生成されるので、気にする必要はありません。

実行例

$ aws-dynamodb-put-item stars "mainStar = 'SUN',
    role='planet', orbitOrder=3,
    name='EARTH', mass=5.97, diameter=12756, density=5514,
    gravity=9.8, escapeVelocity=11.2, rotation=23.9";
OK.

$ aws-dynamodb-put-item stars "mainStar = 'EARTH',
    role='satellite', orbitOrder=1,
    name='MOON', mass=0.0073, diameter=3475, density=3340,
    gravity=1.6, escapeVelocity=2.4, rotation=655.7";
OK.

$

値の型

属性値は、文字列、数値、ブーリアンの3つの型に対応しています。 文字列は引用符でくくられている必要があり、ブーリアンtruefalseのどちらかです。

MAP型のデータを表現するには

MAP型のデータは、属性名をドットで区切ってpath.to.the.subitemという形式で記述します。これによって、指定されたキーの名前を持つMAP型のデータを自動生成します。

2. aws-dynamodb-query - 項目のクエリ

キーを指定してテーブルから項目を抽出します。

aws-dynamodb-query [options] <tableName> <keyConditionExpression>

オプション

オプション 長いオプション 説明
-p –projection-expression=ARG 表示する属性名をカンマ区切りで指定
-f –filter-expression=ARG 検索後のフィルター条件式
-c –max-items=ARG 表示する件数(既定値は20)
-s –sort-item=ARG 表示時に並び替える項目名を指定
-d –desc 降順の並び替えを指定

パラメータ

  • tableName - 操作対象のテーブル名
  • keyConditionExpression - 抽出するキーの条件式を与えます。

実行例

$ aws-dynamodb-query stars 'mainStar="SUN"'\
    --projection-expression 'name,orbitOrder,mass,diameter,
        gravity,density,rotation'\
    --sort-item orbitOrder
Count: 9
ROWNUM mass      rotation name    gravity orbitOrder density diameter
     1    0.33     1407.6 MERCURY     3.7          1    5427     4879
     2    4.87    -5832.0 VENUS       8.9          2    5243    12104
     3    5.97       23.9 MARS        9.8          3    5514    12756
     4    0.642      24.6 MARS        3.7          4    3933     6792
     5 1898.0         9.9 JUPITER    23.1          5    1326   142984
     6  568.0        10.7 SATURN      9.0          6     687   120536
     7   86.8       -17.2 URANUS      8.7          7    1271    51118
     8  102.0        16.1 NEPTUNE    11.0          8    1638    49528
     9    0.0146   -153.3 PLUTO       0.7          9    2095     2370
ScannedCount: 9

$

※ 上記表形式でのコンソール出力は、以下の記事でご紹介している npm list-itを利用しています。

takamints.hatenablog.jp

3. aws-dynamodb-scan - 項目のスキャン

テーブルをScanします。キーの条件式は指定できませんが、その他の使い方はQueryとほぼ同じです。

aws-dynamodb-scan [options] <tableName>

オプション

オプション 長いオプション 説明
-p –projection-expression=ARG 表示する属性名をカンマ区切りで指定
-f –filter-expression=ARG 検索後のフィルター条件式
-c –max-items=ARG 表示する件数(既定値は20)
-s –sort-item=ARG 表示時に並び替える項目名を指定
-d –desc 降順の並び替えを指定

パラメータ

  • tableName - 操作対象のテーブル名

実行例

$ aws-dynamodb-scan stars \
    --projection-expression 'name,orbitOrder,mass,diameter,
        gravity,density,rotation'\
    --filter-expression 'role="planet"'\
    --sort-item orbitOrder --desc
Count: 10
ROWNUM mass      rotation name    gravity orbitOrder density diameter
     1    0.0146   -153.3 PLUTO       0.7          9    2095     2370
     2  102.0        16.1 NEPTUNE    11.0          8    1638    49528
     3   86.8       -17.2 URANUS      8.7          7    1271    51118
     4  568.0        10.7 SATURN      9.0          6     687   120536
     5 1898.0         9.9 JUPITER    23.1          5    1326   142984
     6    0.642      24.6 MARS        3.7          4    3933     6792
     7    5.97       23.9 MARS        9.8          3    5514    12756
     8    4.87    -5832.0 VENUS       8.9          2    5243    12104
     9    0.33     1407.6 MERCURY     3.7          1    5427     4879
ScannedCount: 10

$

共通オプション

以下は各コマンド共通のオプションです。

オプション 長いオプション 説明
-j –output-json AWSのレスポンスを複数行のJSONとして表示
-J –output-json-oneline AWSのレスポンスを1行のJSONとして表示
-h –help ヘルプを表示。

※ ヘルプは、オプションの説明しか表示しません。

参考

オプション --projection-expression--filter-expression--key-condition-expressionと、パラメータkeyConditionExpressionの表記内容や使用可能な演算子については、Query - Amazon DynamoDB、または、Scan - Amazon DynamoDBを参考にしてください。 ただし、プレースホルダ―については、自動的に変換しますので気にしなくて結構です。

制限事項

  • 使用可能な型は、文字列(S)、数字(N)、真偽値(BOOL)、マップ(M)だけです。 リスト(L)はできれば対応したいと思っています。

  • 表示時のカラムの順序は指定できません。一見、projectionExpressionで指定した順番でデータを取得すればよいように思えるのですが、AWSから得られるデータの並びが、この順になっているわけではないからです。とはいえ、なんとか順序を指定できるようにしたいとは思っています。

リポジトリ

その他

同モジュールでは、他にも雑多なコマンドがたくさん含まれていますが、ドキュメントだけでなく動作確認等、まったく追いついていません。

不具合、御要望、改善案などございましたらGitHubのissueでご指摘ください。もちろん他の方法でも構いません。

また、個人的な取り組みとして最近ドキュメントは全て英文でチャレンジしていますので、妙な表現、文法間違い、Typoなど、山ほどあるかと思います。 こちらについても、おかしなところがあれば、ご指摘くださいヨロシクお願いいたします。

AWSへの接続について

※ 以下、~はホームディレクトリを表します。Windowsなら、C:\Users\<ユーザー名>などに読み替えてください。

aws-sdkでは、AWSへの接続のため、以下のAWS CLIで作成される認証情報を使用しているようです。 しかし、同じくAWS CLIが生成するデフォルトリージョンは利用してくれないため、このコマンド独自に読み込んでいます。

認証情報 ~/.aws/credential

[default]
aws_access_key_id = <アクセスキー>
aws_secret_access_key = <シークレットアクセスキー>

コンフィグ ~/.aws/configure

[default]
output = json
region = ap-northeast-1

DynamoDBのプレースホルダーについての基本

DynamoDBのテーブル操作の「式」の中で、プレースホルダ―を使用しなければならないケースがある。プレースホルダ―は以下2種類。

  1. 「属性名のプレースホルダ―」 - 式の中の属性名を置き換える。式の中には予約済みキーワードを表記できないので、属性名が予約済みキーワードとかぶった場合に使用。
  2. 「属性値のプレースホルダ―」 - 式の中の値を置き換えるためのもの。式の中には値を直接表記できないから、全ての値を置き換える必要がある。

予約済みのキーワードが多く、また一般的な単語も多く含まれている。 属性名に関して、予約済みキーワードがどうかにかかわらず全部置き換えても構わない。