LoginSignup
20

More than 5 years have passed since last update.

DynamoDBのJSONサポートをrubyで試す

Posted at

PHPでの記事『DynamoDBのjsonサポートを試してみた。 』があったのでRubyで試してみました。
PHPの方ではSDKがまだJSONを直接扱えるようにライブラリが対応していないので、対応されているはずのRubyでどうなっているか試したメモです。

JSONサポートといっても、DynamoDB側はdata typeを増やしてJSONで必要となる型に対応しているだけで、JSONを処理しているのはSDK側ということですね。(間違ってたらご指摘を!)

結論としては先日リリースされた AWS SDK for Ruby 2 を使えばまぁ大丈夫です。AWS SDK Ruby 2 についてはAWS SDK for Ruby version2 Released!が参考になります。

Gemfile

Gemfileですが、正式リリースされたのはcoreのみのようなので、aws-sdk 全体が必要ならGemfileには

gem "aws-sdk", ">=2.0.0.pre"

を追記すればよいですが、今回はcoreだけでOKなので

gem 'aws-sdk-core', '~> 2.0'

としています。

テーブルの準備

http://aws.amazon.com/jp/blogs/aws/dynamodb-update-json-and-more/ で書かれているデータを使うことにしたので、名前が people で、person_id を Hash Key とするテーブルを作ります。

コードは以下の通り。アクセスキーは適宜修正くださいませ。。。

require 'aws-sdk-core'

dynamo_db = Aws::DynamoDB::Client.new(
  :region => "ap-northeast-1",
  :access_key_id => "XXXXXXXXXXXXXX",
  :secret_access_key => "XXXXXXXXXXXXXXXXXXXXX"
)

resp = dynamo_db.create_table(
  table_name: 'people',
  key_schema: [
    {
    attribute_name: 'person_id',
    key_type: 'HASH',
    },
  ],
  attribute_definitions: [
    {
      attribute_name: 'person_id',
      attribute_type: 'N',
    },
  ],
  provisioned_throughput: {
    read_capacity_units: 1,
    write_capacity_units: 1,
  },
)

puts "table: #{resp.table_description[:table_name]}"
puts "status: #{resp.table_description[:table_status]}"

JSONデータの書き込み

data.jsonを以下のように用意しておく。

{
  "person_id" : 123,
  "last_name" : "Barr",
  "first_name" : "Jeff",
  "current_city" : "Tokyo",
  "next_haircut" :
  {
    "year" : 2014,
    "month" : 10,
    "day" : 30
  },
  "children"  :
    [ "SJB", "ASB", "CGB", "BGB", "GTB" ]
}

で、これを上記で用意したテーブルに入れるコードが下記。

require 'aws-sdk-core'
require 'json'

json_data = JSON.parse(File.read('data.json'))

dynamo_db = Aws::DynamoDB::Client.new(
  :region => "ap-northeast-1",
  :access_key_id => "XXXXXXXXXX",
  :secret_access_key => "XXXXXXXXXXXXXXXXX"
)

resp = dynamo_db.put_item(
  table_name: 'people',
  item: {
    'person_id' => json_data['person_id'],
    'document' => json_data
  }
)

JSONサポートのおかげで、そのまま突っ込めばよいだけですね。ラクです。

JSONデータの読み込み

上で入れたデータを取り出すコードは下記のような感じです。

require 'aws-sdk-core'

dynamo_db = Aws::DynamoDB::Client.new(
  :region => "ap-northeast-1",
  :access_key_id => "XXXXXXXXXXX",
  :secret_access_key => "XXXXXXXXXXXXXXXXXXX"
)

resp = dynamo_db.get_item(
  table_name: "people",
  key: {
    "person_id" => 123,
  },
  attributes_to_get: ["document"],
  consistent_read: true,
)

resp.each do |r|
  p r.item
  puts
  puts JSON.pretty_generate(r.item)
end

実行結果は下記の通りです。(表示の関係で折り返し入れてます)

{"document"=>{"first_name"=>"Jeff", "person_id"=>#<BigDecimal:7faa6d1edb78,'0.123E3',9(18)>,
 "current_city"=>"Tokyo", "next_haircut"=>{"month"=>#<BigDecimal:7faa6d1ed830,'0.1E2',9(18)>,
 "year"=>#<BigDecimal:7faa6d1ed718,'0.2014E4',9(18)>, "day"=>#<BigDecimal:7faa6d1ed600,'0.3E2',9(18)>},
 "last_name"=>"Barr", "children"=>["SJB", "ASB", "CGB", "BGB", "GTB"]}}

{
  "document": {
    "first_name": "Jeff",
    "person_id": "0.123E3",
    "current_city": "Tokyo",
    "next_haircut": {
      "month": "0.1E2",
      "year": "0.2014E4",
      "day": "0.3E2"
    },
    "last_name": "Barr",
    "children": [
      "SJB",
      "ASB",
      "CGB",
      "BGB",
      "GTB"
    ]
  }
}

DynamoDBでのNumber型がrubyのBigDecimalにマッピングされているので、そのままJSON出力すると文字列になってしまいますね。
この点だけ要注意な感じでしょうか。

やはりJSONそのまま使えるのいいですね。
Online IndexingがAvailable Soonということなので検索関連が強化されるのかな。そうするとうれしいですね。
検索条件ももう少し複雑なものができるとさらにうれしいですね。自分的に。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
20