【Ruby】DynamoDBのJSONドキュメントを試してみた(aws-sdk v2.0.0 stable)
ついにDynamoDBがJSONドキュメントに対応されましたね!
NoSQLのAmazon DynamoDBがJSONドキュメントに対応、25GB/月間2億リクエストまで無料枠も拡大 - Publickey
記事にはJavaのサンプルしかなかったので、早速Rubyで試してみました。
今回は「aws-sdk v2.0.0 stable」を使用しています。
put_itemで登録してみる
dynamodb = Aws::DynamoDB::Client.new( access_key_id: '[ACCESSS_KEY]', secret_access_key: '[SECRET_ACCESS_KEY]', region: 'ap-northeast-1' ) dynamodb.put_item( table_name: "Test", item: { # Hash Key "id" => 1, # JSONドキュメント保存(Hashを渡してみる) "json_hash" => { "person_id" => 123, "last_name" => "Barr", "first_name" => "Jeff", "current_city" => nil, "next_haircut" => { "year" => 2014, "month" => 10, "day" => 30 }, "children" => [ "SJB", "ASB", "CGB", "BGB", "GTB" ] }, # JSONドキュメント保存(Arrayを渡してみる) "json_array" => [ { "name" =>"bob", "married" => true, "weight" => 65.3 }, { "name" =>"tom", "married" => false, "weight" => 80.2 }, { "name" =>"michael", "married" => true, "weight" => 57.6 } ] } )
get_itemで登録値を確認してみる
puts dynamodb.get_item( table_name: "Test", key: { "id" => 1 }, consistent_read: true ).item.to_s #出力結果(わかりやすいように整形しています) => { "id" => #<BigDecimal:106a756f0,'0.1E1',9(18)> "json_hash" => { "person_id" => #<BigDecimal:106a761b8,'0.123E3',9(18)>, "last_name" => "Barr", "first_name" => "Jeff", "current_city" => nil, "next_haircut" => { "year" => #<BigDecimal:106a75dd0,'0.2014E4',9(18)>, "month" => #<BigDecimal:106a75ec0,'0.1E2',9(18)>, "day" => #<BigDecimal:106a75cb8,'0.3E2',9(18)> }, "children" => [ "SJB", "ASB", "CGB", "BGB", "GTB" ] }, "json_array" => [ { "name" =>"bob", "married" => true, "weight" => #<BigDecimal:106a76d48,'0.653E2',18(18)> }, { "name" =>"tom", "married" => false, "weight" => #<BigDecimal:106a76a28,'0.802E2',18(18)> }, { "name" =>"michael", "married" => true, "weight" => #<BigDecimal:106a76708,'0.576E2',18(18)> } ] }
ばっちり、HashとArrayで返ってきましたぞ Σ(・ω・ノ)ノ
文字列、真偽値、整数、小数、nullも問題なく扱え、整数と小数はBigDecimalに格納してくれるようです。
もうっ、便利すぎるよ!
※おまけに、aws-sdkはv1しか使ったことなかったので、v2の仕様のシンプルさに感動中(´;ω;`)
update_itemで更新してみる
update_item(attribute_updates:PUT)
attribute_updatesオプションでaction: PUTを指定すると、以下のようにHashとArrayそのものがごっそり置き換わります。
dynamodb.update_item( table_name: "Test", key: { "id" => 1 }, attribute_updates: { "json_hash" => { value: { "test" => "a" }, action: "PUT" }, "json_array" => { value: [ { "name" =>"emily", "married" => false, "weight" => 48.1 } ], action: "PUT" } } ) #get_itemでの取得結果(わかりやすいように整形しています) => { "id" => #<BigDecimal:105ef4f60,'0.1E1',9(18)>, "json_hash" => { "test"=>"a" }, "json_array" => [ { "name"=>"emily", "married"=>false, "weight" => #<BigDecimal:105ef5528,'0.481E2',18(18)> } ] }
update_item(attribute_updates:ADD)
attribute_updatesオプションでaction: ADDを指定した場合、Hashに対して実行しようとすると以下のエラーが発生します。
`call': One or more parameter values were invalid: ADD action is not supported for the type M (Aws::DynamoDB::Errors::ValidationException)
ArrayにADDした場合は、終端に要素が追加されます。
dynamodb.update_item( table_name: "Test", key: { "id" => 1 }, attribute_updates: { "json_array" => { value: [ { "name" =>"emily", "married" => false, "weight" => 48.1 } ], action: "ADD" } } ) #get_itemでの取得結果(json_arrayのみ)(わかりやすいように整形しています) => "json_array" => [ { "name" =>"bob", "married" => true, "weight" => #<BigDecimal:106a76d48,'0.653E2',18(18)> }, { "name" =>"tom", "married" => false, "weight" => #<BigDecimal:106a76a28,'0.802E2',18(18)> }, { "name" =>"michael", "married" => true, "weight" => #<BigDecimal:106a76708,'0.576E2',18(18)> }, { "name" =>"emily", "married" => false, "weight" => #<BigDecimal:106a76528,'0.481E2',18(18)> } ]
update_item(attribute_updates:DELETE)
attribute_updatesオプションのaction: DELETEは、Hash、Arrayともに未対応のようです。
■Hashのエラー
`call': One or more parameter values were invalid: DELETE action with value is not supported for the type M (Aws::DynamoDB::Errors::ValidationException)
■Arrayのエラー
`call': One or more parameter values were invalid: DELETE action with value is not supported for the type L (Aws::DynamoDB::Errors::ValidationException)
update_item (update_expression)
前述の通り、attribute_updatesではJSON内の要素を細かく編集することができません。そういった場合は、update_expressionを使用すると良さそうです。
# 特定の要素を書き換え dynamodb.update_item( table_name: "Test", key: { "id" => 1 }, update_expression: "SET json_hash.current_city = :city", expression_attribute_values: { ":city" => "Osaka" }, ) # 特定の要素を削除 dynamodb.update_item( table_name: "Test", key: { "id" => 1 }, update_expression: "REMOVE json_hash.last_name" )
ただ、update_expressionに複数属性分の処理を記述する方法がわからなかったです。
登録容量
1アイテムの容量は400kbまでです。調子に乗り過ぎて膨大なデータを保存しちゃうと、以下のエラーがでますのでご注意を。
`call': Item size has exceeded the maximum allowed size (Aws::DynamoDB::Errors::ValidationException)
空文字の値を含んだJSONを登録しようとするとエラーになる
たまたま気づいたのですが、例えば以下の様な空文字の値を含んだHashまたはArrayを登録しようとすると、エラーになります。スペースを入れるか、nullを指定するのが良いでしょう。
{ "test" => "" }
`call': One or more parameter values were invalid: An AttributeValue may not contain an empty string (Aws::DynamoDB::Errors::ValidationException)
対応リージョン
現在JSONドキュメントに対応しているリージョンは、
- AmazonのUS East (北バージニア)
- US West(オレゴン)
- Asia Pacific(東京)
- EU(アイルランド)
のみです。昨夜、それに気づかずに、はまっちゃいました orz
未対応リージョンでJSONドキュメントを使用しようとすると、以下のエラーでます。
`call': Supplied AttributeValue is empty, must contain exactly one of the supported datatypes (Aws::DynamoDB::Errors::ValidationException)
やっつけですが、以上になります!良きDynamoライフを!