athens 0.2.0 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +22 -0
- data/Gemfile.lock +18 -15
- data/README.md +32 -6
- data/Rakefile +0 -1
- data/athens.gemspec +4 -3
- data/lib/athens/configuration.rb +5 -3
- data/lib/athens/connection.rb +7 -5
- data/lib/athens/query.rb +29 -42
- data/lib/athens/version.rb +1 -1
- metadata +25 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 763fdc0eeba122974a101d60e8b17045d3d55dcf63f7144fe4db181a6808b858
|
4
|
+
data.tar.gz: 2afff645fa2b925e9317100043a2c574574c7245a99edbc29c8da5c508cb766a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a0e3cf85dfd919a884f90de3bdb1a6896bedc12ed327ae237858ae4182d2565e7d4c19453b2d68f77717ed8763c65ba6565ba654ef34c49aed2273e51d43c5cb
|
7
|
+
data.tar.gz: 387787c6e6f2ab20ff30714374591fd7211fbb9b3181e35df0a0e27fe800444af1d7428c00c7648c1ba2e3b7f1a1e6672574f0e3a38cfa1124d1bcaadd83adcd
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,25 @@
|
|
1
|
+
## 0.3.4 / 2021-03-02
|
2
|
+
|
3
|
+
* Added configurable polling period (thanks [jesseproudman](https://github.com/jesseproudman))
|
4
|
+
|
5
|
+
## 0.3.3 / 2021-01-12
|
6
|
+
|
7
|
+
* Added support for Ruby 3.0 (thanks [blackjiro](https://github.com/blackjiro))
|
8
|
+
|
9
|
+
## 0.3.2 / 2020-11-24
|
10
|
+
|
11
|
+
* Added optional `request_token` and `work_group` parameters to the query execute method (thanks [mediafinger](https://github.com/mediafinger))
|
12
|
+
|
13
|
+
## 0.3.1 / 2020-07-20
|
14
|
+
|
15
|
+
* Bumped development rake version from 0.10 to 0.13 for security fixes
|
16
|
+
* Fixed warning about string defaulting to string (#2)
|
17
|
+
|
18
|
+
## 0.3.0 / 2019-07-02
|
19
|
+
|
20
|
+
* Added enumerator-based result access methods: `#rows` and `#records`
|
21
|
+
* Fixed bug dropping headers from memoized rows across `#to_h` and `#to_a(header_row: true)`
|
22
|
+
|
1
23
|
## 0.2.0 / 2019-03-20
|
2
24
|
|
3
25
|
* Added support for NULL values. Columns with a nullable status of "NULLABLE" or "UNKNOWN" will return nil for NULL values
|
data/Gemfile.lock
CHANGED
@@ -1,33 +1,36 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
athens (0.
|
4
|
+
athens (0.3.4)
|
5
5
|
aws-sdk-athena (~> 1)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
aws-eventstream (1.0
|
11
|
-
aws-partitions (1.
|
12
|
-
aws-sdk-athena (1.
|
13
|
-
aws-sdk-core (~> 3, >= 3.
|
14
|
-
aws-sigv4 (~> 1.
|
15
|
-
aws-sdk-core (3.
|
16
|
-
aws-eventstream (~> 1.0)
|
17
|
-
aws-partitions (~> 1.0)
|
18
|
-
aws-sigv4 (~> 1.
|
10
|
+
aws-eventstream (1.1.0)
|
11
|
+
aws-partitions (1.430.0)
|
12
|
+
aws-sdk-athena (1.35.0)
|
13
|
+
aws-sdk-core (~> 3, >= 3.112.0)
|
14
|
+
aws-sigv4 (~> 1.1)
|
15
|
+
aws-sdk-core (3.112.0)
|
16
|
+
aws-eventstream (~> 1, >= 1.0.2)
|
17
|
+
aws-partitions (~> 1, >= 1.239.0)
|
18
|
+
aws-sigv4 (~> 1.1)
|
19
19
|
jmespath (~> 1.0)
|
20
|
-
aws-sigv4 (1.
|
20
|
+
aws-sigv4 (1.2.2)
|
21
|
+
aws-eventstream (~> 1, >= 1.0.2)
|
21
22
|
jmespath (1.4.0)
|
22
|
-
rake (
|
23
|
+
rake (13.0.1)
|
24
|
+
rexml (3.2.4)
|
23
25
|
|
24
26
|
PLATFORMS
|
25
27
|
ruby
|
26
28
|
|
27
29
|
DEPENDENCIES
|
28
30
|
athens!
|
29
|
-
bundler (
|
30
|
-
rake (~>
|
31
|
+
bundler (>= 1.17)
|
32
|
+
rake (~> 13.0)
|
33
|
+
rexml (~> 3.2)
|
31
34
|
|
32
35
|
BUNDLED WITH
|
33
|
-
|
36
|
+
2.2.5
|
data/README.md
CHANGED
@@ -44,8 +44,8 @@ When your query is done, grab the results as an array:
|
|
44
44
|
```ruby
|
45
45
|
results = query.to_a
|
46
46
|
# [
|
47
|
-
# ['column_1', 'column_2', 'column_3'],
|
48
|
-
# [15, 'data', true],
|
47
|
+
# ['column_1', 'column_2', 'column_3'],
|
48
|
+
# [15, 'data', true],
|
49
49
|
# [20, 'foo', false],
|
50
50
|
# ...
|
51
51
|
# ]
|
@@ -55,12 +55,29 @@ Or as a hash (which is really an array where each row is a hash):
|
|
55
55
|
```ruby
|
56
56
|
results = query.to_h
|
57
57
|
# [
|
58
|
-
# {'column_1': 15, 'column_2': 'data', 'column_3': true},
|
58
|
+
# {'column_1': 15, 'column_2': 'data', 'column_3': true},
|
59
59
|
# {'column_1': 20, 'column_2': 'foo', 'column_3': false},
|
60
60
|
# ...
|
61
61
|
# ]
|
62
62
|
```
|
63
63
|
|
64
|
+
Results are also available as unbuffered enumerators of row arrays:
|
65
|
+
```ruby
|
66
|
+
query.rows.each {|row| ...}
|
67
|
+
# ['column_1', 'column_2', 'column_3']
|
68
|
+
# [15, 'data', true]
|
69
|
+
# [20, 'foo', false],
|
70
|
+
# ...
|
71
|
+
```
|
72
|
+
|
73
|
+
Or hashes:
|
74
|
+
```ruby
|
75
|
+
query.records.each {|record| ...}
|
76
|
+
# {'column_1': 15, 'column_2': 'data', 'column_3': true}
|
77
|
+
# {'column_1': 20, 'column_2': 'foo', 'column_3': false}
|
78
|
+
# ...
|
79
|
+
```
|
80
|
+
|
64
81
|
Athens attempts to parse the sql data types into their ruby equivalents, although there's currently no support for the more complex Array/Map types.
|
65
82
|
|
66
83
|
### Configuration
|
@@ -70,9 +87,10 @@ Configure your AWS settings in an `Athens.configure` block (in rails put this in
|
|
70
87
|
```ruby
|
71
88
|
Athens.configure do |config|
|
72
89
|
config.output_location = "s3://my-bucket/my-folder/athena/results/" # Required
|
73
|
-
config.aws_access_key
|
74
|
-
config.aws_secret_key
|
75
|
-
config.aws_region
|
90
|
+
config.aws_access_key = 'access' # Optional
|
91
|
+
config.aws_secret_key = 'secret' # Optional
|
92
|
+
config.aws_region = 'us-east-1' # Optional
|
93
|
+
config.wait_polling_period = 0.25 # Optional - What period should we poll for the complete query?
|
76
94
|
end
|
77
95
|
```
|
78
96
|
|
@@ -129,6 +147,13 @@ query.cancel # Attempts to cancel an in-progress query, returns true or false
|
|
129
147
|
query.to_a(header_row: false) # If you want your query results returned without a header row of column names
|
130
148
|
```
|
131
149
|
|
150
|
+
The execute method also optionally supports the `request_token` and `work_group` [parameters](https://docs.aws.amazon.com/athena/latest/APIReference/API_StartQueryExecution.html#API_StartQueryExecution_RequestSyntax):
|
151
|
+
|
152
|
+
```ruby
|
153
|
+
conn = Athens::Connection.new(database: 'sample')
|
154
|
+
query = conn.execute("SELECT * FROM mytable", request_token: single_use_token, work_group: my_work_group)
|
155
|
+
```
|
156
|
+
|
132
157
|
## Development
|
133
158
|
|
134
159
|
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.
|
@@ -148,3 +173,4 @@ The gem is available as open source under the terms of the [WTFPL License](http:
|
|
148
173
|
## Code of Conduct
|
149
174
|
|
150
175
|
Everyone interacting in the Athens project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/getletterpress/athens/blob/master/CODE_OF_CONDUCT.md).
|
176
|
+
|
data/Rakefile
CHANGED
data/athens.gemspec
CHANGED
@@ -32,10 +32,11 @@ Gem::Specification.new do |spec|
|
|
32
32
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
33
33
|
spec.require_paths = ["lib"]
|
34
34
|
|
35
|
-
spec.required_ruby_version = '
|
35
|
+
spec.required_ruby_version = '>= 2.4'
|
36
36
|
|
37
37
|
spec.add_dependency "aws-sdk-athena", "~> 1"
|
38
38
|
|
39
|
-
spec.add_development_dependency "bundler", "
|
40
|
-
spec.add_development_dependency "rake", "~>
|
39
|
+
spec.add_development_dependency "bundler", ">= 1.17"
|
40
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
41
|
+
spec.add_development_dependency "rexml", "~> 3.2"
|
41
42
|
end
|
data/lib/athens/configuration.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
module Athens
|
2
2
|
class Configuration
|
3
|
-
attr_accessor :aws_access_key,
|
3
|
+
attr_accessor :aws_access_key,
|
4
4
|
:aws_secret_key,
|
5
5
|
:aws_region,
|
6
|
-
:output_location
|
6
|
+
:output_location,
|
7
|
+
:wait_polling_period
|
7
8
|
|
8
9
|
def initialize
|
9
10
|
@aws_access_key = nil
|
10
11
|
@aws_secret_key = nil
|
11
12
|
@aws_region = nil
|
12
13
|
@output_location = nil
|
14
|
+
@wait_polling_period = 0.25
|
13
15
|
end
|
14
16
|
end
|
15
|
-
end
|
17
|
+
end
|
data/lib/athens/connection.rb
CHANGED
@@ -8,7 +8,7 @@ module Athens
|
|
8
8
|
def initialize(database: nil, aws_client_override: {})
|
9
9
|
@database_name = database
|
10
10
|
|
11
|
-
client_config = {
|
11
|
+
client_config = {
|
12
12
|
access_key_id: Athens.configuration.aws_access_key,
|
13
13
|
secret_access_key: Athens.configuration.aws_secret_key,
|
14
14
|
region: Athens.configuration.aws_region
|
@@ -19,26 +19,28 @@ module Athens
|
|
19
19
|
|
20
20
|
# Runs a query against Athena, returning an Athens::Query object
|
21
21
|
# that you can use to wait for it to finish or get the results
|
22
|
-
def execute(query)
|
22
|
+
def execute(query, request_token: nil, work_group: nil)
|
23
23
|
if @database_name
|
24
24
|
resp = @client.start_query_execution(
|
25
25
|
query_string: query,
|
26
26
|
query_execution_context: context,
|
27
|
-
result_configuration: result_config
|
27
|
+
result_configuration: result_config,
|
28
|
+
client_request_token: request_token,
|
29
|
+
work_group: work_group
|
28
30
|
)
|
29
31
|
else
|
30
32
|
resp = @client.start_query_execution(
|
31
33
|
query_string: query,
|
32
34
|
result_configuration: result_config
|
33
35
|
)
|
34
|
-
end
|
36
|
+
end
|
35
37
|
|
36
38
|
return Athens::Query.new(self, resp.query_execution_id)
|
37
39
|
end
|
38
40
|
|
39
41
|
private
|
40
42
|
|
41
|
-
def context
|
43
|
+
def context
|
42
44
|
Aws::Athena::Types::QueryExecutionContext.new(database: @database_name)
|
43
45
|
end
|
44
46
|
|
data/lib/athens/query.rb
CHANGED
@@ -49,7 +49,7 @@ module Athens
|
|
49
49
|
end
|
50
50
|
|
51
51
|
# Wait a bit and check again
|
52
|
-
sleep(
|
52
|
+
sleep(Athens.configuration.wait_polling_period.to_f)
|
53
53
|
end
|
54
54
|
end
|
55
55
|
|
@@ -69,12 +69,10 @@ module Athens
|
|
69
69
|
end
|
70
70
|
end
|
71
71
|
|
72
|
-
def
|
72
|
+
def rows
|
73
73
|
raise InvalidRequestError.new("Query must be in SUCCEEDED state to return results") unless @state == 'SUCCEEDED'
|
74
74
|
|
75
|
-
|
76
|
-
# Need to load and map all of the rows from the original result
|
77
|
-
@results = []
|
75
|
+
Enumerator.new do |y|
|
78
76
|
result = @connection.client.get_query_results({query_execution_id: @query_execution_id})
|
79
77
|
|
80
78
|
metadata = result.result_set.result_set_metadata
|
@@ -85,53 +83,43 @@ module Athens
|
|
85
83
|
break if rows.empty?
|
86
84
|
|
87
85
|
if first
|
88
|
-
|
86
|
+
y << rows.shift.data.map {|col| col.var_char_value}
|
89
87
|
first = false
|
90
88
|
end
|
91
89
|
|
92
|
-
rows.each
|
93
|
-
@results << map_types(metadata, row)
|
94
|
-
end
|
90
|
+
rows.each {|row| y << map_types(metadata, row)}
|
95
91
|
|
96
|
-
|
97
|
-
result = @connection.client.get_query_results({
|
98
|
-
query_execution_id: @query_execution_id,
|
99
|
-
next_token: result.next_token
|
100
|
-
})
|
101
|
-
else
|
102
|
-
# No more rows, break out and return our mapped data
|
103
|
-
break
|
104
|
-
end
|
105
|
-
end
|
106
|
-
end
|
92
|
+
break unless result.next_token
|
107
93
|
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
94
|
+
result = @connection.client.get_query_results({
|
95
|
+
query_execution_id: @query_execution_id,
|
96
|
+
next_token: result.next_token
|
97
|
+
})
|
98
|
+
end
|
112
99
|
end
|
113
100
|
end
|
114
101
|
|
115
|
-
def
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
headers = all_rows.shift
|
102
|
+
def records
|
103
|
+
Enumerator.new do |y|
|
104
|
+
headers = nil
|
120
105
|
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
map = {}
|
126
|
-
headers.each_with_index do |header, index|
|
127
|
-
map[header] = row[index]
|
128
|
-
end
|
129
|
-
@hash_results << map
|
106
|
+
rows.each_with_index do |row|
|
107
|
+
if headers.nil?
|
108
|
+
headers = row
|
109
|
+
next
|
130
110
|
end
|
111
|
+
|
112
|
+
y << Hash[headers.zip(row)]
|
131
113
|
end
|
132
114
|
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def to_a(header_row: true)
|
118
|
+
(@results ||= rows.to_a).drop(header_row ? 0 : 1)
|
119
|
+
end
|
133
120
|
|
134
|
-
|
121
|
+
def to_h
|
122
|
+
@hash_results ||= records.to_a
|
135
123
|
end
|
136
124
|
|
137
125
|
private
|
@@ -163,7 +151,7 @@ module Athens
|
|
163
151
|
mapped << data.to_i
|
164
152
|
when 'timestamp'
|
165
153
|
mapped << Time.parse(data)
|
166
|
-
when 'varchar'
|
154
|
+
when 'varchar', 'string'
|
167
155
|
mapped << data
|
168
156
|
when 'float', 'double'
|
169
157
|
mapped << data.to_f
|
@@ -185,9 +173,8 @@ module Athens
|
|
185
173
|
end
|
186
174
|
|
187
175
|
return mapped
|
188
|
-
end
|
176
|
+
end
|
189
177
|
|
190
178
|
|
191
179
|
end
|
192
180
|
end
|
193
|
-
|
data/lib/athens/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: athens
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Schulte
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-03-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk-athena
|
@@ -28,14 +28,14 @@ dependencies:
|
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '1.17'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.17'
|
41
41
|
- !ruby/object:Gem::Dependency
|
@@ -44,14 +44,28 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '13.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '13.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rexml
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.2'
|
48
62
|
type: :development
|
49
63
|
prerelease: false
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
66
|
- - "~>"
|
53
67
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
68
|
+
version: '3.2'
|
55
69
|
description: Allows you to easily access AWS Athena databases and run queries
|
56
70
|
email:
|
57
71
|
- chris@oceanbreezesoftware.com
|
@@ -84,13 +98,13 @@ metadata:
|
|
84
98
|
homepage_uri: https://github.com/getletterpress/athens
|
85
99
|
source_code_uri: https://github.com/getletterpress/athens
|
86
100
|
changelog_uri: https://github.com/getletterpress/athens/CHANGELOG.md
|
87
|
-
post_install_message:
|
101
|
+
post_install_message:
|
88
102
|
rdoc_options: []
|
89
103
|
require_paths:
|
90
104
|
- lib
|
91
105
|
required_ruby_version: !ruby/object:Gem::Requirement
|
92
106
|
requirements:
|
93
|
-
- - "
|
107
|
+
- - ">="
|
94
108
|
- !ruby/object:Gem::Version
|
95
109
|
version: '2.4'
|
96
110
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
@@ -99,9 +113,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
99
113
|
- !ruby/object:Gem::Version
|
100
114
|
version: '0'
|
101
115
|
requirements: []
|
102
|
-
|
103
|
-
|
104
|
-
signing_key:
|
116
|
+
rubygems_version: 3.1.4
|
117
|
+
signing_key:
|
105
118
|
specification_version: 4
|
106
119
|
summary: Run simple SQL queries in AWS Athena
|
107
120
|
test_files: []
|