Quantcast
Channel: Node.jsタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 8704

ECS(Node.js + TypeScript)からAWS DynamoDBから最新のデータを1件のみ取得するまで

$
0
0

バッチ処理をNode.js + TypeScriptで作成しており、そのバッチをECS on Fargateで起動しAWS DynamoDBから最新のデータを1件のみ取得する方法を紹介します。

その中でハマったポイントがいくつもあったため、同じ轍を踏むことがないようポイントをまとめておきます。

TL;DR

import*asAWSfrom'aws-sdk';import{DocumentClient}from'aws-sdk/clients/dynamodb';AWS.config.credentials=newAWS.ECSCredentials({httpOptions:{timeout:5000},// 5 second timeoutmaxRetries:10,// retry 10 times});constdynamodb=newAWS.DynamoDB();(async()=>{constparams:DocumentClient.QueryInput={TableName:"Hoge",KeyConditionExpression:"Code = :number",ExpressionAttributeValues:{":number":{"N":"1111"}},ScanIndexForward:false,Limit:1};constdata=awaitdynamodb.query(params,(err,data)=>{if(err){console.log("Error",err);}else{console.log("Success",data);}}).promise();console.log(data.Items[0].hoge.S);})();

ECSからDynamoDBへアクセスする方法

事前準備

事前にECSに付与するためのIAMロールを作成し、DyanamoDBへの権限を有したポリシーをアタッチしておきます。

次にECSのタスク定義、もしくはタスク実行時にタスクロールに先程作成したIAMロールを付与します。

プログラム

AWS.config.credentials=newAWS.ECSCredentials({httpOptions:{timeout:5000},// 5 second timeoutmaxRetries:10,// retry 10 times});

最新の1件を取得するQuery

始めはDocumentClientを利用していましたが、どうやっても上手くいかず最終的にはDocumentClientを使わない方法に落ち着きました。

※ schemaの不一致とエラーになる

(node:1) UnhandledPromiseRejectionWarning: ValidationException: One or more parameter values were invalid: Condition parameter type does not match schema type

※未だに原因がわかっていないので、コメント頂けると嬉しいです

パラメータの型にはDocumentClient.QueryInputを指定します。

この辺はググっても全然情報が出なかったので、sdkのGitHubから引っ張ってようやくわかりましたが、どこかに載ってるのかな??🤔
https://github.com/aws/aws-sdk-js/blob/master/lib/dynamodb/document_client.d.ts

最後に最新の1件のみを取得する方法ですが、Sort Keyが設定されている状態でScanIndexForward: falseを指定すると降順でデータを取得できます。

さらにLimit: 1を指定して、1件のみ取得することが可能です。

constparams:DocumentClient.QueryInput={TableName:"Hoge",KeyConditionExpression:"Code = :number",ExpressionAttributeValues:{":number":{"N":"1111"}},ScanIndexForward:false,// 降順(新しい順)Limit:1// 1件のみ};

ちなみにDynamoDBのNumber型を指定しているカラムも文字列としないとエラーになりましたので、数値が与えられる場合はString型にキャストしたほうが良いみたいです。

Expected params.Item['Code'].N to be a string
ExpressionAttributeValues:{":number":{"N":"1111"}},

おわりに

今回紹介した方法は調べながらトライアンドエラーで解決まで持っていったので、もっと良い方法があるかも知れません。

見識の広い方はコメント頂けると助かります🙏


Viewing all articles
Browse latest Browse all 8704

Trending Articles