dynamodb_model 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +3 -0
- data/Gemfile +6 -0
- data/README.md +99 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/dynamodb_model.gemspec +28 -0
- data/lib/dynamodb_model.rb +9 -0
- data/lib/dynamodb_model/db_config.rb +45 -0
- data/lib/dynamodb_model/item.rb +207 -0
- data/lib/dynamodb_model/migration.rb +17 -0
- data/lib/dynamodb_model/migration/dsl.rb +112 -0
- data/lib/dynamodb_model/version.rb +3 -0
- metadata +113 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7f4086919c79934456c55927f2c127cb983f3f16
|
4
|
+
data.tar.gz: 00da845314f039d065ff7c122c7a7f7d85d33e08
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c47587fa7275602096f3626175abfaf96e8f1c2e538c20558bcee5dc15c69218d92c3dc04c916afad8871a369e0fb1c2a8b84c866e80def1ec316fbffe870be4
|
7
|
+
data.tar.gz: 4b9f9f3754e5d8ec6fd8b6492c40d877fa9d3d4c4b2a310f4addbf677046725c30534a81fc9c78fc57b4c4282db310f77280f483a067eb946c8ba205ecd40d88
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
# DynamodbModel
|
2
|
+
|
3
|
+
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 and the [item_spec.rb](spec/lib/dynamodb_model/item_spec.rb) explain it best:
|
4
|
+
|
5
|
+
## Examples
|
6
|
+
|
7
|
+
First define a class:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
class Post < DynamodbModel::Item
|
11
|
+
# partition_key "id" # optional, defaults to id
|
12
|
+
end
|
13
|
+
```
|
14
|
+
|
15
|
+
### Create
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
post = Post.new
|
19
|
+
post = post.replace(title: "test title")
|
20
|
+
post.attrs # {"id" => "generated-id", title" => "my title"}
|
21
|
+
```
|
22
|
+
|
23
|
+
`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.
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
post = Post.new(id: "myid", title: "my title")
|
27
|
+
post.replace
|
28
|
+
post.attrs # {"id" => "myid", title" => "my title"}
|
29
|
+
```
|
30
|
+
|
31
|
+
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.
|
32
|
+
|
33
|
+
### Find
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
post = Post.find("myid")
|
37
|
+
post.attrs = post.attrs.deep_merge("desc": "my desc") # keeps title field
|
38
|
+
post.replace
|
39
|
+
post.attrs # {"id" => "myid", title" => "my title", desc: "my desc"}
|
40
|
+
```
|
41
|
+
|
42
|
+
The convenience `attrs` method performs a deep_merge:
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
post = Post.find("myid")
|
46
|
+
post.attrs("desc": "my desc 2") # <= does a deep_merge
|
47
|
+
post.replace
|
48
|
+
post.attrs # {"id" => "myid", title" => "my title", desc: "my desc 2"}
|
49
|
+
```
|
50
|
+
|
51
|
+
Note, a race condition edge case can exist when several concurrent replace
|
52
|
+
calls are happening. This is why the interface is called replace to
|
53
|
+
emphasis that possibility.
|
54
|
+
|
55
|
+
### Delete
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
resp = Post.delete("myid")
|
59
|
+
resp # dynamodb client resp
|
60
|
+
```
|
61
|
+
|
62
|
+
### Scan
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
options = {}
|
66
|
+
posts = Post.scan(options)
|
67
|
+
posts # Array of Post items. [Post.new, Post.new, ...]
|
68
|
+
```
|
69
|
+
|
70
|
+
## Installation
|
71
|
+
|
72
|
+
Add this line to your application's Gemfile:
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
gem 'dynamodb_model'
|
76
|
+
```
|
77
|
+
|
78
|
+
And then execute:
|
79
|
+
|
80
|
+
$ bundle
|
81
|
+
|
82
|
+
Or install it yourself as:
|
83
|
+
|
84
|
+
$ gem install dynamodb_model
|
85
|
+
|
86
|
+
## Development
|
87
|
+
|
88
|
+
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.
|
89
|
+
|
90
|
+
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](https://rubygems.org).
|
91
|
+
|
92
|
+
## Contributing
|
93
|
+
|
94
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/tongueroo/dynamodb_model.
|
95
|
+
|
96
|
+
TODO
|
97
|
+
|
98
|
+
* implement Post.query
|
99
|
+
* implement `post.update` with `db.update_item` in a Ruby-ish way
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "dynamodb_model"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require "dynamodb_model/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "dynamodb_model"
|
8
|
+
spec.version = DynamodbModel::VERSION
|
9
|
+
spec.authors = ["Tung Nguyen"]
|
10
|
+
spec.email = ["tongueroo@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{ActiveRecord-ish Dynamodb Model}
|
13
|
+
spec.description = %q{ActiveRecord-ish Dynamodb Model}
|
14
|
+
spec.homepage = "https://github.com/tongueroo/dynamodb_model"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
17
|
+
f.match(%r{^(test|spec|features)/})
|
18
|
+
end
|
19
|
+
spec.bindir = "exe"
|
20
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
|
+
spec.require_paths = ["lib"]
|
22
|
+
|
23
|
+
spec.add_dependency "activesupport"
|
24
|
+
|
25
|
+
spec.add_development_dependency "bundler"
|
26
|
+
spec.add_development_dependency "rake"
|
27
|
+
spec.add_development_dependency "rspec"
|
28
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
$:.unshift(File.expand_path("../", __FILE__))
|
2
|
+
require "dynamodb_model/version"
|
3
|
+
|
4
|
+
module DynamodbModel
|
5
|
+
autoload :Migration, "dynamodb_model/migration"
|
6
|
+
autoload :Dsl, "dynamodb_model/dsl"
|
7
|
+
autoload :DbConfig, "dynamodb_model/db_config"
|
8
|
+
autoload :Item, "dynamodb_model/item"
|
9
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module DynamodbModel::DbConfig
|
2
|
+
def self.included(base)
|
3
|
+
base.extend(ClassMethods)
|
4
|
+
end
|
5
|
+
|
6
|
+
def db
|
7
|
+
self.class.db
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
@@db = nil
|
12
|
+
def db
|
13
|
+
return @@db if @@db
|
14
|
+
|
15
|
+
config = db_config
|
16
|
+
endpoint = ENV['DYNAMODB_ENDPOINT'] || config['endpoint']
|
17
|
+
Aws.config.update(endpoint: endpoint) if endpoint
|
18
|
+
|
19
|
+
@@db ||= Aws::DynamoDB::Client.new
|
20
|
+
end
|
21
|
+
|
22
|
+
# useful for specs
|
23
|
+
def db=(db)
|
24
|
+
@@db = db
|
25
|
+
end
|
26
|
+
|
27
|
+
def db_config
|
28
|
+
if defined?(Jets)
|
29
|
+
YAML.load_file("#{Jets.root}config/dynamodb.yml")[Jets.env] || {}
|
30
|
+
else
|
31
|
+
config_path = ENV['DYNAMODB_MODEL_CONFIG'] || "./config/dynamodb.yml"
|
32
|
+
env = ENV['DYNAMODB_MODEL_ENV'] || "development"
|
33
|
+
YAML.load_file(config_path)[env] || {}
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
@table_namespace = nil
|
38
|
+
def table_namespace
|
39
|
+
return @table_namespace if @table_namespace
|
40
|
+
|
41
|
+
config = db_config
|
42
|
+
@table_namespace = config['table_namespace']
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,207 @@
|
|
1
|
+
require "active_support/core_ext/hash"
|
2
|
+
require "aws-sdk-dynamodb"
|
3
|
+
require "digest"
|
4
|
+
require "yaml"
|
5
|
+
|
6
|
+
# The modeling is ActiveRecord-ish but not exactly because DynamoDB is a
|
7
|
+
# different type of database.
|
8
|
+
#
|
9
|
+
# Examples:
|
10
|
+
#
|
11
|
+
# post = Post.new
|
12
|
+
# post = post.replace(title: "test title")
|
13
|
+
#
|
14
|
+
# post.attrs[:id] now contain a generaetd unique partition_key id.
|
15
|
+
# Usually the partition_key is 'id'. You can set your own unique id also:
|
16
|
+
#
|
17
|
+
# post = Post.new(id: "myid", title: "my title")
|
18
|
+
# post.replace
|
19
|
+
#
|
20
|
+
# Note that the replace method replaces the entire item, so you
|
21
|
+
# need to merge the attributes if you want to keep the other attributes.
|
22
|
+
#
|
23
|
+
# post = Post.find("myid")
|
24
|
+
# post.attrs = post.attrs.deep_merge("desc": "my desc") # keeps title field
|
25
|
+
# post.replace
|
26
|
+
#
|
27
|
+
# The convenience `attrs` method performs a deep_merge:
|
28
|
+
#
|
29
|
+
# post = Post.find("myid")
|
30
|
+
# post.attrs("desc": "my desc") # <= does a deep_merge
|
31
|
+
# post.replace
|
32
|
+
#
|
33
|
+
# Note, a race condition edge case can exist when several concurrent replace
|
34
|
+
# calls are happening. This is why the interface is called replace to
|
35
|
+
# emphasis that possibility.
|
36
|
+
# TODO: implement post.update with db.update_item in a Ruby-ish way.
|
37
|
+
#
|
38
|
+
module DynamodbModel
|
39
|
+
class Item
|
40
|
+
include DbConfig
|
41
|
+
|
42
|
+
def initialize(attrs={})
|
43
|
+
@attrs = attrs
|
44
|
+
end
|
45
|
+
|
46
|
+
# Defining our own reader so we can do a deep merge if user passes in attrs
|
47
|
+
def attrs(*args)
|
48
|
+
case args.size
|
49
|
+
when 0
|
50
|
+
ActiveSupport::HashWithIndifferentAccess.new(@attrs)
|
51
|
+
when 1
|
52
|
+
attributes = args[0] # Hash
|
53
|
+
if attributes.empty?
|
54
|
+
ActiveSupport::HashWithIndifferentAccess.new
|
55
|
+
else
|
56
|
+
@attrs = attrs.deep_merge!(attributes)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Not using method_missing to allow usage of dot notation and assign
|
62
|
+
# @attrs because it might hide actual missing methods errors.
|
63
|
+
# DynamoDB attrs can go many levels deep so it makes less make sense to
|
64
|
+
# use to dot notation.
|
65
|
+
|
66
|
+
# The method is named replace to clearly indicate that the item is
|
67
|
+
# fully replaced.
|
68
|
+
def replace
|
69
|
+
attrs = self.class.replace(@attrs)
|
70
|
+
@attrs = attrs # refresh attrs because it now has the id
|
71
|
+
end
|
72
|
+
|
73
|
+
def find(id)
|
74
|
+
self.class.find(id)
|
75
|
+
end
|
76
|
+
|
77
|
+
def table_name
|
78
|
+
self.class.table_name
|
79
|
+
end
|
80
|
+
|
81
|
+
def partition_key
|
82
|
+
self.class.partition_key
|
83
|
+
end
|
84
|
+
|
85
|
+
def to_attrs
|
86
|
+
@attrs
|
87
|
+
end
|
88
|
+
|
89
|
+
# Longer hand methods for completeness.
|
90
|
+
# Internallly encourage the shorter attrs method.
|
91
|
+
def attributes=(attributes)
|
92
|
+
@attributes = attributes
|
93
|
+
end
|
94
|
+
|
95
|
+
def attributes
|
96
|
+
@attributes
|
97
|
+
end
|
98
|
+
|
99
|
+
# AWS Docs examples: http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GettingStarted.Ruby.04.html
|
100
|
+
# Usage:
|
101
|
+
#
|
102
|
+
# Post.scan(
|
103
|
+
# expression_attribute_names: {"#updated_at"=>"updated_at"},
|
104
|
+
# filter_expression: "#updated_at between :start_time and :end_time",
|
105
|
+
# expression_attribute_values: {
|
106
|
+
# ":start_time" => "2010-01-01T00:00:00",
|
107
|
+
# ":end_time" => "2020-01-01T00:00:00"
|
108
|
+
# }
|
109
|
+
# )
|
110
|
+
#
|
111
|
+
# TODO: pretty lame interface, improve it somehow. Maybe:
|
112
|
+
#
|
113
|
+
# Post.scan(filter: "updated_at between :start_time and :end_time")
|
114
|
+
#
|
115
|
+
# which automatically maps the structure.
|
116
|
+
def self.scan(params={})
|
117
|
+
puts("Should not use scan for production. It's slow and expensive. You should create either a LSI or GSI and use query the index instead.")
|
118
|
+
|
119
|
+
defaults = {
|
120
|
+
table_name: table_name
|
121
|
+
}
|
122
|
+
params = defaults.merge(params)
|
123
|
+
resp = db.scan(params)
|
124
|
+
resp.items.map {|i| Post.new(i) }
|
125
|
+
end
|
126
|
+
|
127
|
+
def self.replace(attrs)
|
128
|
+
# Automatically adds some attributes:
|
129
|
+
# partition key unique id
|
130
|
+
# created_at and updated_at timestamps. Timestamp format from AWS docs: http://amzn.to/2z98Bdc
|
131
|
+
defaults = {
|
132
|
+
partition_key => Digest::SHA1.hexdigest([Time.now, rand].join)
|
133
|
+
}
|
134
|
+
item = defaults.merge(attrs)
|
135
|
+
item["created_at"] ||= Time.now.utc.strftime('%Y-%m-%dT%TZ')
|
136
|
+
item["updated_at"] = Time.now.utc.strftime('%Y-%m-%dT%TZ')
|
137
|
+
|
138
|
+
# put_item full replaces the item
|
139
|
+
resp = db.put_item(
|
140
|
+
table_name: table_name,
|
141
|
+
item: item
|
142
|
+
)
|
143
|
+
|
144
|
+
# The resp does not contain the attrs. So might as well return
|
145
|
+
# the original item with the generated partition_key value
|
146
|
+
item
|
147
|
+
end
|
148
|
+
|
149
|
+
def self.find(id)
|
150
|
+
resp = db.get_item(
|
151
|
+
table_name: table_name,
|
152
|
+
key: {partition_key => id}
|
153
|
+
)
|
154
|
+
attributes = resp.item # unwraps the item's attributes
|
155
|
+
Post.new(attributes) if attributes
|
156
|
+
end
|
157
|
+
|
158
|
+
# Two ways to use the delete method:
|
159
|
+
#
|
160
|
+
# 1. Specify the key as a String. In this case the key will is the partition_key
|
161
|
+
# set on the model.
|
162
|
+
# MyModel.delete("728e7b5df40b93c3ea6407da8ac3e520e00d7351")
|
163
|
+
#
|
164
|
+
# 2. Specify the key as a Hash, you can arbitrarily specific the key structure this way
|
165
|
+
# MyModel.delete("728e7b5df40b93c3ea6407da8ac3e520e00d7351")
|
166
|
+
#
|
167
|
+
# options is provided in case you want to specific condition_expression or
|
168
|
+
# expression_attribute_values.
|
169
|
+
def self.delete(key_object, options={})
|
170
|
+
if key_object.is_a?(String)
|
171
|
+
key = {
|
172
|
+
partition_key => key_object
|
173
|
+
}
|
174
|
+
else # it should be a Hash
|
175
|
+
key = key_object
|
176
|
+
end
|
177
|
+
|
178
|
+
params = {
|
179
|
+
table_name: table_name,
|
180
|
+
key: key
|
181
|
+
}
|
182
|
+
# In case you want to specify condition_expression or expression_attribute_values
|
183
|
+
params = params.merge(options)
|
184
|
+
|
185
|
+
resp = db.delete_item(params)
|
186
|
+
end
|
187
|
+
|
188
|
+
# When called with an argument we'll set the internal @partition_key value
|
189
|
+
# When called without an argument just retun it.
|
190
|
+
# class Comment < DynamodbModel::Item
|
191
|
+
# partition_key "post_id"
|
192
|
+
# end
|
193
|
+
def self.partition_key(*args)
|
194
|
+
case args.size
|
195
|
+
when 0
|
196
|
+
@partition_key || "id" # defaults to id
|
197
|
+
when 1
|
198
|
+
@partition_key = args[0].to_s
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
def self.table_name
|
203
|
+
@table_name = self.name.pluralize.underscore
|
204
|
+
[table_namespace, @table_name].reject {|s| s.nil? || s.empty?}.join('-')
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module DynamodbModel
|
2
|
+
class Migration
|
3
|
+
autoload :Dsl, "dynamodb_model/migration/dsl"
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def up
|
7
|
+
puts "Running up migration for #{self.class.name}"
|
8
|
+
end
|
9
|
+
|
10
|
+
def create_table(table_name)
|
11
|
+
dsl = Dsl.new(table_name)
|
12
|
+
yield(dsl)
|
13
|
+
dsl.execute
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
class DynamodbModel::Migration
|
2
|
+
class Dsl
|
3
|
+
include DynamodbModel::DbConfig
|
4
|
+
|
5
|
+
ATTRIBUTE_TYPE_MAP = {
|
6
|
+
'string' => 'S',
|
7
|
+
'number' => 'N',
|
8
|
+
'binary' => 'B',
|
9
|
+
's' => 'S',
|
10
|
+
'n' => 'N',
|
11
|
+
'b' => 'B',
|
12
|
+
}
|
13
|
+
|
14
|
+
attr_accessor :key_schema, :attribute_definitions
|
15
|
+
# db is the dynamodb client
|
16
|
+
def initialize(table_name)
|
17
|
+
@table_name = table_name
|
18
|
+
@key_schema = []
|
19
|
+
@attribute_definitions = []
|
20
|
+
@provisioned_throughput = {
|
21
|
+
read_capacity_units: 10,
|
22
|
+
write_capacity_units: 10
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
# http://docs.aws.amazon.com/sdkforruby/api/Aws/DynamoDB/Types/KeySchemaElement.html
|
27
|
+
# partition_key is required
|
28
|
+
def partition_key(identifier)
|
29
|
+
adjust_schema_and_attributes(identifier, "hash")
|
30
|
+
end
|
31
|
+
|
32
|
+
# sort_key is optional
|
33
|
+
def sort_key(identifier)
|
34
|
+
adjust_schema_and_attributes(identifier, "range")
|
35
|
+
end
|
36
|
+
|
37
|
+
# Parameters:
|
38
|
+
# identifier: "id:string" or "id"
|
39
|
+
# key_type: "hash" or "range"
|
40
|
+
#
|
41
|
+
# Adjusts the parameters for create_table to add the
|
42
|
+
# partition_key and sort_key
|
43
|
+
def adjust_schema_and_attributes(identifier, key_type)
|
44
|
+
name, attribute_type = identifier.split(':')
|
45
|
+
attribute_type = "string" if attribute_type.nil?
|
46
|
+
|
47
|
+
partition_key = {
|
48
|
+
attribute_name: name,
|
49
|
+
key_type: key_type.upcase
|
50
|
+
}
|
51
|
+
@key_schema << partition_key
|
52
|
+
|
53
|
+
attribute_definition = {
|
54
|
+
attribute_name: name,
|
55
|
+
attribute_type: ATTRIBUTE_TYPE_MAP[attribute_type]
|
56
|
+
}
|
57
|
+
@attribute_definitions << attribute_definition
|
58
|
+
end
|
59
|
+
|
60
|
+
# t.provisioned_throughput(5) # both
|
61
|
+
# t.provisioned_throughput(:read, 5)
|
62
|
+
# t.provisioned_throughput(:write, 5)
|
63
|
+
# t.provisioned_throughput(:both, 5)
|
64
|
+
def provisioned_throughput(*params)
|
65
|
+
case params.size
|
66
|
+
when 2
|
67
|
+
capacity_type, capacity_units = params
|
68
|
+
when 1
|
69
|
+
arg = params[0]
|
70
|
+
if arg.is_a?(Hash)
|
71
|
+
@provisioned_throughput = arg # set directly
|
72
|
+
return
|
73
|
+
else # assume parameter is an Integer
|
74
|
+
capacity_type = :both
|
75
|
+
capacity_units = arg
|
76
|
+
end
|
77
|
+
when 0 # reader method
|
78
|
+
return @provisioned_throughput
|
79
|
+
end
|
80
|
+
|
81
|
+
map = {
|
82
|
+
read: :read_capacity_units,
|
83
|
+
write: :write_capacity_units,
|
84
|
+
}
|
85
|
+
|
86
|
+
if capacity_type = :both
|
87
|
+
@provisioned_throughput[map[:read]] = capacity_units
|
88
|
+
@provisioned_throughput[map[:write]] = capacity_units
|
89
|
+
else
|
90
|
+
@provisioned_throughput[capacity_type] = capacity_units
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def execute
|
95
|
+
params = {
|
96
|
+
table_name: @table_ame,
|
97
|
+
key_schema: @key_schema,
|
98
|
+
attribute_definitions: @attribute_definitions,
|
99
|
+
provisioned_throughput: @provisioned_throughput
|
100
|
+
}
|
101
|
+
begin
|
102
|
+
result = db.create_table(params)
|
103
|
+
|
104
|
+
puts 'DynamoDB Table: proj-posts Status: ' +
|
105
|
+
result.table_description.table_status;
|
106
|
+
rescue Aws::DynamoDB::Errors::ServiceError => error
|
107
|
+
puts 'Unable to create table:'
|
108
|
+
puts error.message
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
metadata
ADDED
@@ -0,0 +1,113 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dynamodb_model
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tung Nguyen
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-11-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: ActiveRecord-ish Dynamodb Model
|
70
|
+
email:
|
71
|
+
- tongueroo@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- ".gitignore"
|
77
|
+
- ".rspec"
|
78
|
+
- Gemfile
|
79
|
+
- README.md
|
80
|
+
- Rakefile
|
81
|
+
- bin/console
|
82
|
+
- bin/setup
|
83
|
+
- dynamodb_model.gemspec
|
84
|
+
- lib/dynamodb_model.rb
|
85
|
+
- lib/dynamodb_model/db_config.rb
|
86
|
+
- lib/dynamodb_model/item.rb
|
87
|
+
- lib/dynamodb_model/migration.rb
|
88
|
+
- lib/dynamodb_model/migration/dsl.rb
|
89
|
+
- lib/dynamodb_model/version.rb
|
90
|
+
homepage: https://github.com/tongueroo/dynamodb_model
|
91
|
+
licenses: []
|
92
|
+
metadata: {}
|
93
|
+
post_install_message:
|
94
|
+
rdoc_options: []
|
95
|
+
require_paths:
|
96
|
+
- lib
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
requirements: []
|
108
|
+
rubyforge_project:
|
109
|
+
rubygems_version: 2.6.14
|
110
|
+
signing_key:
|
111
|
+
specification_version: 4
|
112
|
+
summary: ActiveRecord-ish Dynamodb Model
|
113
|
+
test_files: []
|