DynamodbModel
A simple wrapper library to make DynamoDB usage a little more friendly. The modeling is ActiveRecord-ish but not exactly because DynamoDB is a different type of database. Examples below explain it best:
Examples
First define a class:
class Post < DynamodbModel::Item
# partition_key "id" # optional, defaults to id
end
Create
post = Post.new
post = post.replace(title: "test title")
post.attrs # {"id" => "generated-id", title" => "my title"}
post.attrs[:id]
now contain a generated unique partition_key id. Usually the partition_key is 'id'. You can set your own unique id also by specifying id.
post = Post.new(id: "myid", title: "my title")
post.replace
post.attrs # {"id" => "myid", title" => "my title"}
Note that the replace method replaces the entire item, so you need to merge the attributes if you want to keep the other attributes. Know this is weird, but this is how DynamoDB works.
Find
post = Post.find("myid")
post.attrs = post.attrs.deep_merge("desc": "my desc") # keeps title field
post.replace
post.attrs # {"id" => "myid", title" => "my title", desc: "my desc"}
The convenience attrs
method performs a deep_merge:
post = Post.find("myid")
post.attrs("desc": "my desc 2") # <= does a deep_merge
post.replace
post.attrs # {"id" => "myid", title" => "my title", desc: "my desc 2"}
Note, a race condition edge case can exist when several concurrent replace calls are happening. This is why the interface is called replace to emphasis that possibility.
Delete
resp = Post.delete("myid") # dynamodb client resp
# or
post = Post.find("myid")
resp = post.delete # dynamodb client resp
Scan
= {}
posts = Post.scan()
posts # Array of Post items. [Post.new, Post.new, ...]
Query
posts = Post.query(
index_name: 'category-index',
expression_attribute_names: { "#category_name" => "category" },
expression_attribute_values: { ":category_value" => "Entertainment" },
key_condition_expression: "#category_name = :category_value",
)
posts # Array of Post items. [Post.new, Post.new, ...]
Where
The where could be prettied up. Appreciate any pull requests.
Post.where({category: "Drama"}, {index_name: "category-index"})
Examples are also in item_spec.rb.
Migration Support
DynamodbModel supports ActiveRecord-like migrations. Here's a short example:
class CreateCommentsMigration < DynamodbModel::Migration
def up
create_table :comments do |t|
t.partition_key "post_id:string" # required
t.sort_key "created_at:string" # optional
t.provisioned_throughput(5) # sets both read and write, defaults to 5 when not set
end
end
end
More examples are in the docs/migrations folder.
Installation
Add this line to your application's Gemfile:
gem 'dynamodb_model'
And then execute:
$ bundle
Or install it yourself as:
$ gem install dynamodb_model
Development
After checking out the repo, run bin/setup
to install dependencies. You can also run bin/console
for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run bundle exec rake install
. To release a new version, update the version number in version.rb
, and then run bundle exec rake release
, which will create a git tag for the version, push git commits and tags, and push the .gem
file to rubygems.org.
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/tongueroo/dynamodb_model.
TODO
- improve Post.where. Something like
Post.index_name("user_id").where(category_name: "Entertainment")
would be nice. - implement
post.update
withdb.update_item
in a Ruby-ish way