beetle_etl 0.0.2 → 0.0.7
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/Gemfile +6 -0
- data/beetle_etl.gemspec +5 -6
- data/lib/beetle_etl.rb +7 -12
- data/lib/beetle_etl/dsl/dsl.rb +11 -12
- data/lib/beetle_etl/dsl/transformation.rb +10 -3
- data/lib/beetle_etl/dsl/transformation_loader.rb +13 -5
- data/lib/beetle_etl/import.rb +11 -4
- data/lib/beetle_etl/naming.rb +37 -0
- data/lib/beetle_etl/steps/assign_ids.rb +14 -38
- data/lib/beetle_etl/steps/create_stage.rb +59 -0
- data/lib/beetle_etl/steps/drop_stage.rb +15 -0
- data/lib/beetle_etl/steps/load.rb +46 -61
- data/lib/beetle_etl/steps/map_relations.rb +8 -14
- data/lib/beetle_etl/steps/step.rb +1 -8
- data/lib/beetle_etl/steps/table_diff.rb +68 -89
- data/lib/beetle_etl/steps/transform.rb +2 -4
- data/lib/beetle_etl/version.rb +1 -1
- data/spec/beetle_etl_spec.rb +3 -25
- data/spec/dsl/dsl_spec.rb +8 -15
- data/spec/dsl/transformation_loader_spec.rb +11 -4
- data/spec/dsl/transformation_spec.rb +40 -4
- data/spec/feature/example_schema.rb +2 -137
- data/spec/feature/example_transform.rb +13 -6
- data/spec/feature/feature_spec.rb +119 -18
- data/spec/steps/assign_ids_spec.rb +23 -28
- data/spec/steps/create_stage_spec.rb +89 -0
- data/spec/steps/load_spec.rb +15 -23
- data/spec/steps/map_relations_spec.rb +32 -36
- data/spec/steps/table_diff_spec.rb +41 -45
- data/spec/steps/transform_spec.rb +2 -0
- data/spec/{dependency_resolver_spec.rb → task_runner/dependency_resolver_spec.rb} +0 -0
- metadata +22 -36
- data/lib/beetle_etl/state.rb +0 -67
- data/spec/import_spec.rb +0 -7
- data/spec/state_spec.rb +0 -124
File without changes
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: beetle_etl
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luciano Maiwald
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-02-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sequel
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 4.
|
19
|
+
version: 4.0.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 4.
|
26
|
+
version: 4.0.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -39,75 +39,61 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.6'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: 3.0.0
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
54
|
+
version: 3.0.0
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - "~>"
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: 3.1.0
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - "~>"
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: 3.1.0
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: pg
|
56
|
+
name: timecop
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
72
58
|
requirements:
|
73
59
|
- - ">="
|
74
60
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
61
|
+
version: 0.7.0
|
76
62
|
type: :development
|
77
63
|
prerelease: false
|
78
64
|
version_requirements: !ruby/object:Gem::Requirement
|
79
65
|
requirements:
|
80
66
|
- - ">="
|
81
67
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
68
|
+
version: 0.7.0
|
83
69
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
70
|
+
name: pg
|
85
71
|
requirement: !ruby/object:Gem::Requirement
|
86
72
|
requirements:
|
87
73
|
- - ">="
|
88
74
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
75
|
+
version: 0.18.0
|
90
76
|
type: :development
|
91
77
|
prerelease: false
|
92
78
|
version_requirements: !ruby/object:Gem::Requirement
|
93
79
|
requirements:
|
94
80
|
- - ">="
|
95
81
|
- !ruby/object:Gem::Version
|
96
|
-
version:
|
82
|
+
version: 0.18.0
|
97
83
|
- !ruby/object:Gem::Dependency
|
98
84
|
name: activesupport
|
99
85
|
requirement: !ruby/object:Gem::Requirement
|
100
86
|
requirements:
|
101
87
|
- - ">="
|
102
88
|
- !ruby/object:Gem::Version
|
103
|
-
version:
|
89
|
+
version: 4.2.0
|
104
90
|
type: :development
|
105
91
|
prerelease: false
|
106
92
|
version_requirements: !ruby/object:Gem::Requirement
|
107
93
|
requirements:
|
108
94
|
- - ">="
|
109
95
|
- !ruby/object:Gem::Version
|
110
|
-
version:
|
96
|
+
version: 4.2.0
|
111
97
|
description: Taking care of synchronizing external data with referential data in your
|
112
98
|
application.
|
113
99
|
email:
|
@@ -128,8 +114,10 @@ files:
|
|
128
114
|
- lib/beetle_etl/dsl/transformation.rb
|
129
115
|
- lib/beetle_etl/dsl/transformation_loader.rb
|
130
116
|
- lib/beetle_etl/import.rb
|
131
|
-
- lib/beetle_etl/
|
117
|
+
- lib/beetle_etl/naming.rb
|
132
118
|
- lib/beetle_etl/steps/assign_ids.rb
|
119
|
+
- lib/beetle_etl/steps/create_stage.rb
|
120
|
+
- lib/beetle_etl/steps/drop_stage.rb
|
133
121
|
- lib/beetle_etl/steps/load.rb
|
134
122
|
- lib/beetle_etl/steps/map_relations.rb
|
135
123
|
- lib/beetle_etl/steps/step.rb
|
@@ -140,17 +128,15 @@ files:
|
|
140
128
|
- lib/beetle_etl/version.rb
|
141
129
|
- script/postgres
|
142
130
|
- spec/beetle_etl_spec.rb
|
143
|
-
- spec/dependency_resolver_spec.rb
|
144
131
|
- spec/dsl/dsl_spec.rb
|
145
132
|
- spec/dsl/transformation_loader_spec.rb
|
146
133
|
- spec/dsl/transformation_spec.rb
|
147
134
|
- spec/feature/example_schema.rb
|
148
135
|
- spec/feature/example_transform.rb
|
149
136
|
- spec/feature/feature_spec.rb
|
150
|
-
- spec/import_spec.rb
|
151
137
|
- spec/spec_helper.rb
|
152
|
-
- spec/state_spec.rb
|
153
138
|
- spec/steps/assign_ids_spec.rb
|
139
|
+
- spec/steps/create_stage_spec.rb
|
154
140
|
- spec/steps/load_spec.rb
|
155
141
|
- spec/steps/map_relations_spec.rb
|
156
142
|
- spec/steps/step_spec.rb
|
@@ -159,6 +145,7 @@ files:
|
|
159
145
|
- spec/support/database.yml.example
|
160
146
|
- spec/support/database.yml.travis
|
161
147
|
- spec/support/database_helpers.rb
|
148
|
+
- spec/task_runner/dependency_resolver_spec.rb
|
162
149
|
homepage: https://github.com/maiwald/beetle_etl
|
163
150
|
licenses:
|
164
151
|
- MIT
|
@@ -185,17 +172,15 @@ specification_version: 4
|
|
185
172
|
summary: BeetleETL helps you with your recurring ETL imports.
|
186
173
|
test_files:
|
187
174
|
- spec/beetle_etl_spec.rb
|
188
|
-
- spec/dependency_resolver_spec.rb
|
189
175
|
- spec/dsl/dsl_spec.rb
|
190
176
|
- spec/dsl/transformation_loader_spec.rb
|
191
177
|
- spec/dsl/transformation_spec.rb
|
192
178
|
- spec/feature/example_schema.rb
|
193
179
|
- spec/feature/example_transform.rb
|
194
180
|
- spec/feature/feature_spec.rb
|
195
|
-
- spec/import_spec.rb
|
196
181
|
- spec/spec_helper.rb
|
197
|
-
- spec/state_spec.rb
|
198
182
|
- spec/steps/assign_ids_spec.rb
|
183
|
+
- spec/steps/create_stage_spec.rb
|
199
184
|
- spec/steps/load_spec.rb
|
200
185
|
- spec/steps/map_relations_spec.rb
|
201
186
|
- spec/steps/step_spec.rb
|
@@ -204,3 +189,4 @@ test_files:
|
|
204
189
|
- spec/support/database.yml.example
|
205
190
|
- spec/support/database.yml.travis
|
206
191
|
- spec/support/database_helpers.rb
|
192
|
+
- spec/task_runner/dependency_resolver_spec.rb
|
data/lib/beetle_etl/state.rb
DELETED
@@ -1,67 +0,0 @@
|
|
1
|
-
module BeetleETL
|
2
|
-
|
3
|
-
ImportAleadyRunning = Class.new(StandardError)
|
4
|
-
ImportSchemaNotFound = Class.new(StandardError)
|
5
|
-
ImportNotRunning = Class.new(StandardError)
|
6
|
-
|
7
|
-
class State
|
8
|
-
|
9
|
-
def start_import
|
10
|
-
raise ImportAleadyRunning if import_already_running?
|
11
|
-
|
12
|
-
@run_id = import_runs_dataset.insert(
|
13
|
-
state: 'RUNNING',
|
14
|
-
started_at: now
|
15
|
-
)
|
16
|
-
end
|
17
|
-
|
18
|
-
def mark_as_succeeded
|
19
|
-
mark_as('SUCCEEDED')
|
20
|
-
end
|
21
|
-
|
22
|
-
def mark_as_failed
|
23
|
-
mark_as('FAILED')
|
24
|
-
end
|
25
|
-
|
26
|
-
def run_id
|
27
|
-
raise ImportNotRunning if @run_id.nil?
|
28
|
-
@run_id
|
29
|
-
end
|
30
|
-
|
31
|
-
def last_run_id
|
32
|
-
last_import = import_runs_dataset.
|
33
|
-
select(:id).
|
34
|
-
where(state: 'SUCCEEDED').
|
35
|
-
order(Sequel.desc(:id)).
|
36
|
-
first
|
37
|
-
|
38
|
-
last_import.nil? ? nil : last_import[:id]
|
39
|
-
end
|
40
|
-
|
41
|
-
private
|
42
|
-
|
43
|
-
def import_runs_table
|
44
|
-
"#{BeetleETL.config.stage_schema}__import_runs".to_sym
|
45
|
-
end
|
46
|
-
|
47
|
-
def import_already_running?
|
48
|
-
import_runs_dataset.where(state: 'RUNNING').count > 0
|
49
|
-
end
|
50
|
-
|
51
|
-
def now
|
52
|
-
Time.now
|
53
|
-
end
|
54
|
-
|
55
|
-
def mark_as(state)
|
56
|
-
import_runs_dataset.filter(id: run_id).update(
|
57
|
-
state: state,
|
58
|
-
finished_at: now
|
59
|
-
)
|
60
|
-
end
|
61
|
-
|
62
|
-
def import_runs_dataset
|
63
|
-
BeetleETL.database[import_runs_table]
|
64
|
-
end
|
65
|
-
|
66
|
-
end
|
67
|
-
end
|
data/spec/import_spec.rb
DELETED
data/spec/state_spec.rb
DELETED
@@ -1,124 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
require 'active_support/core_ext/date/calculations'
|
4
|
-
require 'active_support/core_ext/numeric/time'
|
5
|
-
|
6
|
-
module BeetleETL
|
7
|
-
describe State do
|
8
|
-
subject { State.new }
|
9
|
-
|
10
|
-
before do
|
11
|
-
BeetleETL.configure do |config|
|
12
|
-
config.stage_schema = 'stage'
|
13
|
-
config.database = test_database
|
14
|
-
end
|
15
|
-
|
16
|
-
test_database.create_schema 'stage'
|
17
|
-
test_database.create_table :stage__import_runs do
|
18
|
-
primary_key :id
|
19
|
-
String :state, size: 10, null: false
|
20
|
-
DateTime :started_at, null: false
|
21
|
-
DateTime :finished_at
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
describe '#start_import' do
|
26
|
-
let(:now) { 1.minute.ago.beginning_of_day }
|
27
|
-
|
28
|
-
it 'registers a new import in the import_runs table' do
|
29
|
-
allow(subject).to receive(:now) { now }
|
30
|
-
|
31
|
-
subject.start_import
|
32
|
-
|
33
|
-
expect(:stage__import_runs).to have_values(
|
34
|
-
[ :id , :state , :started_at , :finished_at ] ,
|
35
|
-
[ 1 , 'RUNNING' , now , nil ]
|
36
|
-
)
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'raises an exception if there is alreay an import marked as running' do
|
40
|
-
insert_into(:stage__import_runs).values(
|
41
|
-
[ :id , :state , :started_at , :finished_at ] ,
|
42
|
-
[ 1 , 'RUNNING' , now , nil ]
|
43
|
-
)
|
44
|
-
|
45
|
-
expect { subject.start_import }.to raise_exception(BeetleETL::ImportAleadyRunning)
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
context 'run ids' do
|
50
|
-
before do
|
51
|
-
insert_into(:stage__import_runs).values(
|
52
|
-
[ :state , :started_at , :finished_at ] ,
|
53
|
-
[ 'FAILED' , 8.days.ago , 7.days.ago ] ,
|
54
|
-
[ 'SUCCEEDED' , 6.days.ago , 5.day.ago ] ,
|
55
|
-
[ 'SUCCEEDED' , 4.days.ago , 3.days.ago ] ,
|
56
|
-
[ 'FAILED' , 2.days.ago , 1.day.ago ] ,
|
57
|
-
)
|
58
|
-
end
|
59
|
-
|
60
|
-
describe '#run_id' do
|
61
|
-
it 'returns the import‘s id after it has been started' do
|
62
|
-
subject.start_import
|
63
|
-
expect(subject.run_id).to eql(5)
|
64
|
-
end
|
65
|
-
|
66
|
-
it 'raises an exception when the import has not been started' do
|
67
|
-
expect { subject.run_id }.to raise_exception(BeetleETL::ImportNotRunning)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
describe '#last_run_id' do
|
72
|
-
it 'returns nil if there is no last successful import' do
|
73
|
-
test_database[:stage__import_runs].update(state: 'FAILED')
|
74
|
-
|
75
|
-
subject.start_import
|
76
|
-
expect(subject.last_run_id).to be_nil
|
77
|
-
end
|
78
|
-
|
79
|
-
it 'returns the id of the last successul import' do
|
80
|
-
subject.start_import
|
81
|
-
expect(subject.last_run_id).to eql(3)
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
context 'marking imports' do
|
87
|
-
let(:now) { 1.minute.ago.beginning_of_day }
|
88
|
-
let(:one_day_ago) { 1.day.ago.beginning_of_day }
|
89
|
-
|
90
|
-
before do
|
91
|
-
insert_into(:stage__import_runs).values(
|
92
|
-
[ :state , :started_at , :finished_at ] ,
|
93
|
-
[ 'SUCCEEDED' , 2.days.ago , one_day_ago ] ,
|
94
|
-
)
|
95
|
-
allow(subject).to receive(:now) { now }
|
96
|
-
subject.start_import
|
97
|
-
end
|
98
|
-
|
99
|
-
describe '#mark_as_failed' do
|
100
|
-
it 'marks the current import as FAILED' do
|
101
|
-
subject.mark_as_failed
|
102
|
-
|
103
|
-
expect(:stage__import_runs).to have_values(
|
104
|
-
[ :id , :state , :finished_at ] ,
|
105
|
-
[ 1 , 'SUCCEEDED' , one_day_ago ] ,
|
106
|
-
[ 2 , 'FAILED' , now ] ,
|
107
|
-
)
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
describe '#mark_as_succeeded' do
|
112
|
-
it 'marks the current import as SUCCEEDED' do
|
113
|
-
subject.mark_as_succeeded
|
114
|
-
|
115
|
-
expect(:stage__import_runs).to have_values(
|
116
|
-
[ :id , :state , :finished_at ] ,
|
117
|
-
[ 1 , 'SUCCEEDED' , one_day_ago ] ,
|
118
|
-
[ 2 , 'SUCCEEDED' , now ] ,
|
119
|
-
)
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|