田舎の技術者が奮闘中

php ruby node.js javascript などのスクリプト言語とサーバー(Chef、Vagrant)に関して書きます。

rubyとAWS SDKでDynamoDBを操作する。

DESIGN HUNTER | デザインハンター | ホームページデザイン ウェブデザイン まとめ | デザイン解析

新しいサービスを作成した際にものすごくDynamoDBにハマったので、同じくハマっている人のためにブログに残しておきます。

まずいちばん問題だったのが、まったく参考サイトが無いということ。
AWSのAPIドキュメントとか確認しながらやったのですが、なんせ英語が弱いのでかなり苦労しました。
あとは、実際のSDKのコードを追いながらこまめに動作確認してました。

DESIGN HUNTER | デザインハンター | ホームページデザイン ウェブデザイン まとめ | デザイン解析でDynamoDBを使おうと思った背景ですが、使ってみたかったという好奇心が一番でした。

で、使ってみて率直な感想ですが、結構癖があるんじゃないか?と思いました。
と言ってもKVSなんてmongoDB(そもそもmongoDBはRDBに近い要素もあるので、使いやすかったです。)ぐらいしか使ったことなかったので、癖があるかどうかはよく判りません・・・
でも、発想を駆使すればDynamoDBだけでもサイトが構築できる!と感じました。


問題点もいくつかあります。
そこは諦めるか、プログラムで回避するしかありません。

問題点1
ORDER BYが無い!
探したのですが、結局ORDER BYに関する情報は見当たりませんでした。orz
実は方法がありました。別記事としてまとめてます。
DynamoDBのorder byに関して - 田舎の技術者が奮闘中

問題点2
DynamoDBに値を入れる際に、入れた順番でデータが入ってくれません。日付順とかも出来ませんでした。そこはプログラムで回避しなさいということでしょうか・・判りませんが・・

問題点3
リレーション出来ない。
KVSだったら普通なんですけれど、これも一応問題点として上げておきます。
プログラムで回避するしか方法はありません。

他にもあると思いますが、自分が構築していく上では3点だけでした。


まずAWSのコンソール画面からDynamoDBのテーブルを作らないといけませんが、その部分は省略します。(もちろんプログラムでもテーブル作成出来ます。)
今回はテーブル名を「table」にし、ハッシュキーを「id」にします。レンジキーは使いません。

ここからプログラムになります。
これが正しいかどうか判りませんが動作します。
もっと良い書き方があるのであれば教えて下さい><

SDKインストール

gem install aws-sdk

キーの読み込み

access_key_idとsecret_access_keyの説明は省略します。
dynamo_db_endpointは日本のDynamoDBを見に行くような設定です。
必ず設定して下さい。

AWS.config(
           :access_key_id => '***',
           :secret_access_key => '***',
           :dynamo_db_endpoint => 'dynamodb.ap-northeast-1.amazonaws.com'
           )

テーブル名の設定とスキーマを設定する。

こちらの設定も必須となります。
スキーマはハッシュキーだけ設定しておけばOKです。

dynamo_db = AWS::DynamoDB.new
table = dynamo_db.tables["table"]
table.hash_key = [:id, :string]

データを書き込む

追加したいカラムがあったら追加するだけです。ここはRDBと違って便利ですね。

table.items.create({:id => "a1234", :title => "hogehoge"})
# 新たにkeywordというカラムを追加したい場合は
table.items.create({:id => "a1234", :title => "hogehoge", :keyword =>"keyword"})

データをアップデートする(ハッシュキーからの更新)

table.items["a1234"].attributes.update do |u|
  u.set :title => "hugahuga"
end
# 複数カラム更新の場合
table.items["a1234"].attributes.update do |u|
  u.set :title => "hogehoge_update"
  u.set :keyword => "keyword_update"
end

データをアップデートする(ハッシュキー以外から更新)

table.items.where(:title).contains("hogehoge").each{ |u|
   u.attributes.update do |i|
      i.set :title => "hogehoge_update"
  end
}

データを削除する

table.items["a1234"].delete

データをまとめて削除する。

titleが「hogehoge」とマッチするレコードを削除します。

table.items.where(:title).contains("hogehoge").each do |u|
  u.delete
end

他にもありますが、基本的なことはこれだけで出来ます。
色々とハマりましたが、一つ一つメソッドを確認しながら対応すれば、確実に実装できると思います。

次回はページングでもやりますかね・・・