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
他にもありますが、基本的なことはこれだけで出来ます。
色々とハマりましたが、一つ一つメソッドを確認しながら対応すれば、確実に実装できると思います。
次回はページングでもやりますかね・・・