DynamoRecord
Provides helpful rake tasks and model extensions on top of aws-record.
Installation
Add this line to your application's Gemfile:
gem 'dynamo-record'
And then execute:
$ bundle
Or install it yourself as:
$ gem install dynamo-record
Usage
Models
In app/models, create a class that includes DynamoRecord::Model and contains
one or more of the
standard set
of attribute declarations, along with the following new composite attribute
types:
composite_string_attrcomposite_integer_attr
An example file:
class MyModel
include DynamoRecord::Model
composite_string_attr(
:model_key,
hash_key: true,
parts: [:model_id, :account_id]
)
integer_attr :position, range_key: true
string_attr :user_id
float_attr :score
map_attr :map_value
end
The partition key is labeled with hash_key: true. The sort key is labeled with
range_key: true.
Declaring secondary indexes are included in aws-record and are defined
here.
As an example, a global secondary index can be defined as follows:
global_secondary_index(
:user_idx,
hash_key: :user_id,
range_key: :score,
projection: {
projection_type: 'INCLUDE',
non_key_attributes: [
:map_value
]
}
)
As an example, a local secondary index can be defined as follows:
local_secondary_index(
:score_idx,
range_key: :score,
projection: {
projection_type: 'INCLUDE',
non_key_attributes: [
:map_value
]
}
)
The full documentation for projection_type and non_key_attributes can be
found here.
Query Helpers
Query helpers are included as class methods.
composite_key(*args)
For models that have composite attributes, create a composite key value from the individual attribute parts:
hash_key = MyModel.composite_key('model_1', 'account_1')
split_composite(string)
Split a composite attribute value into its individual attribute parts:
model_id, acccount_id = MyModel.split_composite(hash_key)
find_all_by_hash_key(hash_key_value, opts = {})
Find all item instances that match a given hash key value. opts are options
passed to the underlying query.
MyModel.find_all_by_hash_key(hash_key)
find_all_by_gsi_hash_key(gsi_name, hash_key_value, opts = {})
Find all item instances using a global secondary instance using a hash key
value. opts are options passed to the underlying query.
MyModel.find_all_by_gsi_hash_key('user_idx', 'user_1')
find_all_by_gsi_hash_and_range_keys(gsi_name, hash_key_value, range_key_value)
Find all item instances using a global secondary instance using a hash key value and range key value.
MyModel.find_all_by_gsi_hash_key('user_idx', 'user_1', 0.0)
find_all_by_lsi_hash_key(lsi_name, hash_key_value, opts = {})
Find all item instances using a local secondary instance using a hash key value.
opts are options passed to the underlying query.
MyModel.find_all_by_lsi_hash_key('score_idx', 'user_1')
find_all_by_lsi_hash_and_range_keys(lsi_name, hash_key_value, range_key_value)
Find all item instances using a local secondary instance using a hash key value and range key value.
MyModel.find_all_by_lsi_hash_key('score_idx', 'user_1', 0.0)
Migrations
Dynamo migration files are stored in db/dynamo_migrate. The name of the file
follows the style of standard Rails migration files like
YYYYMMDDHHMMSS_create_model_1.rb. A migration file that creates a Dynamo table
looks like:
module DynamoMigrate
class CreateMyModel < DynamoRecord::TableMigration
def self.up
migrate(MyModel) do |migration|
migration.create!(
provisioned_throughput: {
read_capacity_units: 1,
write_capacity_units: 1
},
global_secondary_index_throughput: {
user_idx: {
read_capacity_units: 1,
write_capacity_units: 1
}
}
)
end
end
end
end
Note that the throughput of the table can be configured separately from the throughput of the secondary index.
A migration file that creates a Dynamo stream looks like:
module DynamoMigrate
class AddMyModelStream < DynamoRecord::TableMigration
def self.update
add_stream(MyModel)
end
end
end