ja ja en en ja en ja ja ja ja ja ja ja ja ja ja en ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja en ja ja ja en ja ja ja en ja ja en ja en ja ja ja ja ja en nl ja pl en ja nb ja ja nb ja ja nb ja ja en ja ja ja ja ja en ja ja ja ja ja ja ja ja ja ja ja ja ja ja ja jbo en en ja nl nb en ko it en it it it en fr it ja ja en la fi ja it it it pt it de en ja en en it fr it en it nb it ja ja ja ja en ja ja ja ja ja ja ja ja ja
PowerShellでDynamoDBにJSONドキュメントを格納する - Sanwa Systems Tech Blog
Add-Type -Path "C:\Program Files (x86)\AWS Tools\PowerShell\AWSPowerShell\AWSSDK.Core.dll" Add-Type -Path "C:\Program Files (x86)\AWS Tools\PowerShell\AWSPowerShell\AWSSDK.DynamoDBv2.dll" $accessKey = "********************"; $secretAccessKey = "****************************************"; $endPoint = [Amazon.RegionEndpoint]::APNortheast1; $client = New-Object Amazon.DynamoDBv2.AmazonDynamoDBClient($accessKey, $secretAccessKey, $endPoint); $tableName = "YOUR-TABLE-NAME" # 自分で作ったテーブル名 $table = [Amazon.DynamoDBv2.DocumentModel.Table]::LoadTable($client, $tableName); $document = [Amazon.DynamoDBv2.DocumentModel.Document]::FromJson('{...}') # 引数はJSON形式のテキスト $table.PutItem($document)
前提条件は以下の通りです。
DynamoDBでテーブルを作成してあること
IAMユーザーを作成し、適切な権限が割り当ててあること
IAMユーザーのAPIキーを作成してあること
AWS Tools for Windows PowerShellがインストール済みであること
PowerShell 3.0以上
以下はこのコードの説明です。
DLLを直接読み込めば大抵のことはできる
上述の AWS Tools for Windows PowerShell をインストールすると、自動的に環境変数PSModulePath*1へSDKのパスが追加され、特に何かを意識しなくてもGet-EC2InstanceやStart-EC2InstanceといったAWSのためのコマンドレットが使えるようになります。しかしリファレンスを参照すると分かるように、現時点では項目の追加・削除・編集のためのコマンドレットは用意されていません。そのためには(上のコードのように)直接SDKの中のコードを呼び出す必要があります。
そんなときはAdd-Typeで直接DLLを読み込んでしまいましょう。
PS C:\> [Amazon.RegionEndPoint]::APNortheast1 型 [Amazon.RegionEndPoint] が見つかりません。この型を含むアセンブリが読み込まれていることを確認してください。 発生場所 行:1 文字:1 + [Amazon.RegionEndPoint]::APNortheast1 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (Amazon.RegionEndPoint:TypeName) []、RuntimeException + FullyQualifiedErrorId : TypeNotFound PS C:\> Add-Type -Path "C:\Program Files (x86)\AWS Tools\PowerShell\AWSPowerShell\AWSSDK.Core.dll" PS C:\> [Amazon.RegionEndPoint]::APNortheast1 SystemName DisplayName ---------- ----------- ap-northeast-1 Asia Pacific (Tokyo)
このようにアセンブリが直接ロードできて使えるようになります。
DynamoDBの準備をする
まずDynamoDBのテーブルを作成します。パーティーションキー、ソートキーを適当に設定しました。なお、このキーは1度作ったらもう変更できません(変えたければテーブルを作り直して移行する必要があります)。
これができたら、このテーブルを触る権限を持ったIAMユーザーを準備し、APIキーを取得しておきます。
レコードを登録・更新・削除する
まず空のテーブルへレコードを実際に登録してみます。レコードをまずPowerShellの連想配列@{Key1=値1; Key2=値2; ...}で作成し、JSON形式のテキストを介してAmazon.DynamoDBv2.DocumentModel.DynamoDBEntryクラスのインスタンスに変換してからDynamoDBへ送信しています。
# 投入するデータ $source = @( @{name = "Tama"; timestamp = "2015-12-04T00:00:00.000Z"; cuteness = 90; mood = "暇"}, @{name = "Tama"; timestamp = "2015-12-04T01:00:00.000Z"; cuteness = 100; mood = "とても暇"}, @{name = "Tama"; timestamp = "2015-12-04T02:00:00.000Z"; cuteness = "INF"; mood = "睡眠"}, @{name = "Wak"; timestamp = "2015-12-04T00:00:00.000Z"; cuteness = 0; mood = "腹減った"; memo = "ラーメン" }) $source | % { $json = $_ | ConvertTo-Json -Compress $document = [Amazon.DynamoDBv2.DocumentModel.Document]::FromJson($json) $table.PutItem($document) }
登録結果はManagement Consoleから確認することができます。cutenessの型は数値だったり文字列だったり、memoはあったりなかったりしますが、それでもDynamoDBは柔軟に受け入れてくれています。
テーブルを作るときに決めたキー(ここではnameとtimestamp)が両方とも完全に一致するレコードを登録すると更新になります。つまりPutItemはSQLのINSERT文ではなくMERGE/UPSERT文に相当するわけです。したがって次のコードはデータ部分以外は上と同じです。memoに入れ子にした連想配列をセットしてみました。
$source = @( @{name = "Tama"; timestamp = "2015-12-04T02:00:00.000Z"; cuteness = "INF"; mood = "睡眠"; memo = "あおむけ"}, # 更新 @{name = "Tama"; timestamp = "2015-12-04T03:00:00.000Z"; cuteness = 100; mood = "ごはん"; memo = @{menu = "高級かりかり"; ammount = 2 }}) $source | % { $json = $_ | ConvertTo-Json -Compress $document = [Amazon.DynamoDBv2.DocumentModel.Document]::FromJson($json) $table.PutItem($document) }
1行は更新、1行は新規追加になりました。memoカラムにはJSONが生で書いてあるように見えますが、よく見ると"N"や"S"といった見覚えのないキーが出てきています。これはDynamoDBが自動的に与えた型情報です。こちらもきちんと入れ子構造を持ったドキュメントとして管理されている証だと思ってください。
ついでに削除も試しておきます。こちらも構文はまったく同じで、とにかくキーを指定してレコードを特定できればそれが処理対象になると考えればいいです。
$removed = @{name = "Wak"; timestamp = "2015-12-04T00:00:00.000Z"} | ConvertTo-JSON -Compress $document = [Amazon.DynamoDBv2.DocumentModel.Document]::FromJson($removed) $table.DeleteItem($document)
次は検索を行います。検索に相当するコマンドレットも用意されていないので、やはりこちらもSDKを直接呼び出します。たとえば SELECT * FROM helloDynamoDB WHERE cuteness > 80 に相当するスキャン*2なら、カラム名、演算子、値を順に指定して
$scanFilter = New-Object Amazon.DynamoDBv2.DocumentModel.ScanFilter $scanFilter.AddCondition("cuteness", [Amazon.DynamoDBv2.DocumentModel.ScanOperator]::GreaterThan, 80) $search = $table.Scan($scanFilter)
で検索ができます。この時点で得られる$searchはカーソルのようなもので、実際の結果はGetNextSet()を呼び出して取得します(カーソルとは違って1件ずつではなく、最大1MB分のデータがまとめて返されます)。
PS C:\> $search = $table.Scan($scanFilter) PS C:\> $documentList = $search.GetNextSet() PS C:\> $documentList Key Value --- ----- timestamp 2015-12-04T00:00:00.000Z mood 暇 name Tama cuteness 90 timestamp 2015-12-04T01:00:00.000Z mood とても暇 name Tama cuteness 100
確かに2件の結果が取得できました。
今回はPowerShellからDynamoDBを利用する方法について書きました。次回はAWS ConfigのログをDynamoDBに格納し、PowerShellから検索して変更履歴を出力するという(多少は)実用的な用途に使ってみたいと思います。お楽しみに!
*1:ここで指定されたパスに配置されたモジュールは自動的に読み込まれるようになります。環境変数PATHのPowerShell版だと思えばだいたい合っています
*2:インデックスを使わないテーブルスキャンのようなものだと考えてください。したがって低速ですがすべての項目が検索対象に指定できます。テーブル作成時に指定したnameを使う検索なら、「スキャン」ではなく高速な「クエリ」が利用できます
nurenezumi 2015-12-04 19:26
API Gateway + LambdaでSlackのCustom Commandを作る
こんにちは、AWS担当のwakです。先日このような記事を書いたの…
AWS LambdaからGoogle APIを呼び出す
こんにちは、AWS担当のwakです。間が空いてしまったので、今回…
AWS LambdaのパラメータをDynamoDBで管理する
こんにちは、AWS担当のwakです。前回に続きAWS Lambdaの話をし…
Node.js+Dynamo DBでレコードを検索する
こんにちは、AWS担当のwakです。 前回・前々回の記事ではLambda…
CloudWatchの監視結果をSlackに流す(AWS Lambdaバージョン)
こんにちは、AWS担当のwakです。 自分が書いた過去の記事を読み…
« VisualStudioチームエクスプローラーでのG… C#でEF+LINQを用いてMySQLを使用するメリ… »