active_record_data_loader 1.0.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/build.yml +51 -0
- data/.github/workflows/gem-push.yml +29 -0
- data/.rubocop.yml +39 -6
- data/CHANGELOG.md +42 -0
- data/Gemfile.lock +68 -66
- data/README.md +91 -8
- data/Rakefile +8 -2
- data/active_record_data_loader.gemspec +8 -5
- data/config/database.yml +9 -0
- data/docker-compose.yml +18 -0
- data/gemfiles/activerecord_6.gemfile +1 -1
- data/lib/active_record_data_loader/active_record/belongs_to_configuration.rb +1 -1
- data/lib/active_record_data_loader/active_record/column_configuration.rb +14 -4
- data/lib/active_record_data_loader/active_record/datetime_value_generator.rb +21 -0
- data/lib/active_record_data_loader/active_record/enum_value_generator.rb +28 -5
- data/lib/active_record_data_loader/active_record/integer_value_generator.rb +2 -2
- data/lib/active_record_data_loader/active_record/model_data_generator.rb +15 -2
- data/lib/active_record_data_loader/active_record/per_row_value_cache.rb +33 -0
- data/lib/active_record_data_loader/active_record/polymorphic_belongs_to_configuration.rb +1 -1
- data/lib/active_record_data_loader/active_record/text_value_generator.rb +1 -1
- data/lib/active_record_data_loader/bulk_insert_strategy.rb +4 -3
- data/lib/active_record_data_loader/configuration.rb +45 -3
- data/lib/active_record_data_loader/connection_handler.rb +74 -0
- data/lib/active_record_data_loader/connection_output_adapter.rb +20 -0
- data/lib/active_record_data_loader/copy_strategy.rb +20 -20
- data/lib/active_record_data_loader/file_output_adapter.rb +40 -0
- data/lib/active_record_data_loader/loader.rb +11 -27
- data/lib/active_record_data_loader/version.rb +1 -1
- data/lib/active_record_data_loader.rb +26 -14
- metadata +60 -11
- data/.travis.yml +0 -23
- data/config/database.yml.travis +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8ae60492b342e71d8a1a2e20aff31794af784f1009346f4d5dc4375dd939bb48
|
4
|
+
data.tar.gz: ab5be5bdf1cb5af69f5f8a1ac65ea8f64ee1338398c7f6cae6e15e6276d2e954
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8b860a06433a0661a765428f37df596ac0b3fd46ff447fbf3edfa5cf50f89dcda0f146b25074959ca5aee792dff153a56eb37888075ae10649d6cde1e598c53d
|
7
|
+
data.tar.gz: dc9b43011f8c1b8c7b663b650b5ba11e43b9dd040a8ef6b7a58b24c7da903b1c963104a06c39f45e5ebaa4f01e815d8d6d565ded2fd9b5a186dcd50ed69b2e7c
|
@@ -0,0 +1,51 @@
|
|
1
|
+
name: Build
|
2
|
+
|
3
|
+
on: [push, workflow_dispatch]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
build:
|
7
|
+
name: Build + Test
|
8
|
+
runs-on: ubuntu-latest
|
9
|
+
services:
|
10
|
+
postgres:
|
11
|
+
image: postgres:11
|
12
|
+
ports:
|
13
|
+
- "2345:5432"
|
14
|
+
env:
|
15
|
+
POSTGRES_USER: test
|
16
|
+
POSTGRES_PASSWORD: test
|
17
|
+
mysql:
|
18
|
+
image: mysql:5
|
19
|
+
ports:
|
20
|
+
- "3306:3306"
|
21
|
+
env:
|
22
|
+
MYSQL_ROOT_PASSWORD: test
|
23
|
+
MYSQL_USER: test
|
24
|
+
MYSQL_PASSWORD: test
|
25
|
+
MYSQL_DATABASE: test
|
26
|
+
strategy:
|
27
|
+
matrix:
|
28
|
+
ruby: [2.5.9, 2.6.7, 2.7.3]
|
29
|
+
gemfile: [activerecord_5, rails, faker, ffaker]
|
30
|
+
env:
|
31
|
+
BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile
|
32
|
+
steps:
|
33
|
+
- name: Checkout
|
34
|
+
uses: actions/checkout@v2
|
35
|
+
|
36
|
+
- name: Setup ruby
|
37
|
+
uses: ruby/setup-ruby@v1
|
38
|
+
with:
|
39
|
+
ruby-version: ${{ matrix.ruby }}
|
40
|
+
bundler-cache: true
|
41
|
+
|
42
|
+
- name: Wait for DBs to be ready
|
43
|
+
run: bundle exec rake wait_for_test_db
|
44
|
+
|
45
|
+
- name: Run tests
|
46
|
+
run: bundle exec rake
|
47
|
+
|
48
|
+
- name: Coveralls
|
49
|
+
uses: coverallsapp/github-action@master
|
50
|
+
with:
|
51
|
+
github-token: ${{ secrets.github_token }}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
name: Ruby Gem
|
2
|
+
|
3
|
+
on: workflow_dispatch
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
build:
|
7
|
+
name: Build + Publish
|
8
|
+
runs-on: ubuntu-latest
|
9
|
+
permissions:
|
10
|
+
contents: read
|
11
|
+
packages: write
|
12
|
+
|
13
|
+
steps:
|
14
|
+
- uses: actions/checkout@v2
|
15
|
+
- name: Set up Ruby 2.6
|
16
|
+
uses: actions/setup-ruby@v1
|
17
|
+
with:
|
18
|
+
ruby-version: 2.6.x
|
19
|
+
|
20
|
+
- name: Publish to RubyGems
|
21
|
+
run: |
|
22
|
+
mkdir -p $HOME/.gem
|
23
|
+
touch $HOME/.gem/credentials
|
24
|
+
chmod 0600 $HOME/.gem/credentials
|
25
|
+
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
26
|
+
gem build *.gemspec
|
27
|
+
gem push *.gem
|
28
|
+
env:
|
29
|
+
GEM_HOST_API_KEY: "${{ secrets.RUBYGEMS_API_KEY }}"
|
data/.rubocop.yml
CHANGED
@@ -1,5 +1,20 @@
|
|
1
1
|
AllCops:
|
2
|
-
TargetRubyVersion: 2.
|
2
|
+
TargetRubyVersion: 2.5
|
3
|
+
NewCops: enable
|
4
|
+
SuggestExtensions: false
|
5
|
+
|
6
|
+
Layout/LineLength:
|
7
|
+
Max: 110
|
8
|
+
Exclude: ["*.gemspec"]
|
9
|
+
|
10
|
+
Layout/SpaceAroundMethodCallOperator:
|
11
|
+
Enabled: true
|
12
|
+
|
13
|
+
Lint/RaiseException:
|
14
|
+
Enabled: true
|
15
|
+
|
16
|
+
Lint/StructNewOverride:
|
17
|
+
Enabled: true
|
3
18
|
|
4
19
|
Lint/UnusedMethodArgument:
|
5
20
|
AllowUnusedKeywordArguments: true
|
@@ -11,20 +26,38 @@ Metrics/AbcSize:
|
|
11
26
|
Metrics/BlockLength:
|
12
27
|
Exclude: ["spec/**/*", "*.gemspec"]
|
13
28
|
|
14
|
-
Metrics/
|
15
|
-
|
16
|
-
Exclude: ["*.gemspec"]
|
29
|
+
Metrics/ClassLength:
|
30
|
+
Exclude: ["spec/**/*", "*.gemspec"]
|
17
31
|
|
18
32
|
Metrics/MethodLength:
|
19
33
|
Max: 15
|
20
34
|
Exclude: ["spec/**/*"]
|
21
35
|
|
22
|
-
|
23
|
-
|
36
|
+
Metrics/ParameterLists:
|
37
|
+
Max: 5
|
38
|
+
Exclude: ["lib/active_record_data_loader/configuration.rb"]
|
39
|
+
|
40
|
+
Style/CaseLikeIf:
|
41
|
+
Enabled: false
|
24
42
|
|
25
43
|
Style/Documentation:
|
26
44
|
Enabled: false
|
27
45
|
|
46
|
+
Style/ExponentialNotation:
|
47
|
+
Enabled: true
|
48
|
+
|
49
|
+
Style/FrozenStringLiteralComment:
|
50
|
+
Exclude: ["gemfiles/*"]
|
51
|
+
|
52
|
+
Style/HashEachMethods:
|
53
|
+
Enabled: true
|
54
|
+
|
55
|
+
Style/HashTransformKeys:
|
56
|
+
Enabled: true
|
57
|
+
|
58
|
+
Style/HashTransformValues:
|
59
|
+
Enabled: true
|
60
|
+
|
28
61
|
Style/StringLiterals:
|
29
62
|
EnforcedStyle: double_quotes
|
30
63
|
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# Change log
|
2
|
+
|
3
|
+
## [v1.2.0] - 2021-11-14
|
4
|
+
|
5
|
+
[Diff](https://github.com/abeiderman/active_record_data_loader/compare/v1.1.0...v1.2.0)
|
6
|
+
|
7
|
+
### Changes:
|
8
|
+
* Add `:file` output option for generating a SQL script instead of loading the data into the database.
|
9
|
+
* Fix some connection handling issues when a custom connection factory is provided.
|
10
|
+
|
11
|
+
## [v1.1.0] - 2021-05-01
|
12
|
+
|
13
|
+
[Diff](https://github.com/abeiderman/active_record_data_loader/compare/v1.0.2...v1.1.0)
|
14
|
+
|
15
|
+
### Changes:
|
16
|
+
* Bump ruby version requirement to >= 2.5
|
17
|
+
* Bump activerecord requirement to >= 5.0
|
18
|
+
|
19
|
+
## [v1.0.2] - 2019-07-05
|
20
|
+
|
21
|
+
[Diff](https://github.com/abeiderman/active_record_data_loader/compare/v1.0.1...v1.0.2)
|
22
|
+
|
23
|
+
### Changes:
|
24
|
+
* Add support for MySQL enums
|
25
|
+
* Accept a connection factory lambda as part of the configuration
|
26
|
+
|
27
|
+
## [v1.0.1] - 2019-06-16
|
28
|
+
|
29
|
+
[Diff](https://github.com/abeiderman/active_record_data_loader/compare/v1.0.0...v1.0.1)
|
30
|
+
|
31
|
+
### Changes:
|
32
|
+
* Generate values for datetime column types. This also fixes the fact that `created_at` and `updated_at` were not being populated by default.
|
33
|
+
|
34
|
+
## [v1.0.0] - 2019-06-15
|
35
|
+
|
36
|
+
Initial stable release
|
37
|
+
|
38
|
+
[v1.0.0]: https://github.com/abeiderman/active_record_data_loader/releases/tag/v1.0.0
|
39
|
+
[v1.0.1]: https://github.com/abeiderman/active_record_data_loader/releases/tag/v1.0.1
|
40
|
+
[v1.0.2]: https://github.com/abeiderman/active_record_data_loader/releases/tag/v1.0.2
|
41
|
+
[v1.1.0]: https://github.com/abeiderman/active_record_data_loader/releases/tag/v1.1.0
|
42
|
+
[v1.2.0]: https://github.com/abeiderman/active_record_data_loader/releases/tag/v1.2.0
|
data/Gemfile.lock
CHANGED
@@ -1,107 +1,109 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
active_record_data_loader (1.
|
5
|
-
activerecord (>=
|
4
|
+
active_record_data_loader (1.2.0)
|
5
|
+
activerecord (>= 5.0)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
activemodel (
|
11
|
-
activesupport (=
|
12
|
-
activerecord (
|
13
|
-
activemodel (=
|
14
|
-
activesupport (=
|
15
|
-
|
16
|
-
activesupport (5.2.3)
|
10
|
+
activemodel (6.1.4.1)
|
11
|
+
activesupport (= 6.1.4.1)
|
12
|
+
activerecord (6.1.4.1)
|
13
|
+
activemodel (= 6.1.4.1)
|
14
|
+
activesupport (= 6.1.4.1)
|
15
|
+
activesupport (6.1.4.1)
|
17
16
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
18
|
-
i18n (>=
|
19
|
-
minitest (
|
20
|
-
tzinfo (~>
|
17
|
+
i18n (>= 1.6, < 2)
|
18
|
+
minitest (>= 5.1)
|
19
|
+
tzinfo (~> 2.0)
|
20
|
+
zeitwerk (~> 2.3)
|
21
21
|
appraisal (2.2.0)
|
22
22
|
bundler
|
23
23
|
rake
|
24
24
|
thor (>= 0.14.0)
|
25
|
-
|
26
|
-
ast (2.4.0)
|
25
|
+
ast (2.4.2)
|
27
26
|
coderay (1.1.2)
|
28
|
-
concurrent-ruby (1.1.
|
29
|
-
coveralls (0.8.23)
|
30
|
-
json (>= 1.8, < 3)
|
31
|
-
simplecov (~> 0.16.1)
|
32
|
-
term-ansicolor (~> 1.3)
|
33
|
-
thor (>= 0.19.4, < 2.0)
|
34
|
-
tins (~> 1.6)
|
27
|
+
concurrent-ruby (1.1.9)
|
35
28
|
diff-lcs (1.3)
|
36
|
-
docile (1.
|
37
|
-
i18n (1.
|
29
|
+
docile (1.4.0)
|
30
|
+
i18n (1.8.11)
|
38
31
|
concurrent-ruby (~> 1.0)
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
method_source (~> 0.9.0)
|
32
|
+
method_source (1.0.0)
|
33
|
+
minitest (5.14.4)
|
34
|
+
mysql2 (0.5.3)
|
35
|
+
parallel (1.21.0)
|
36
|
+
parser (3.0.2.0)
|
37
|
+
ast (~> 2.4.1)
|
38
|
+
pg (1.2.3)
|
39
|
+
pry (0.13.1)
|
40
|
+
coderay (~> 1.1)
|
41
|
+
method_source (~> 1.0)
|
50
42
|
rainbow (3.0.0)
|
51
|
-
rake (
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
rspec-
|
56
|
-
|
43
|
+
rake (13.0.1)
|
44
|
+
regexp_parser (2.1.1)
|
45
|
+
rexml (3.2.5)
|
46
|
+
rspec (3.9.0)
|
47
|
+
rspec-core (~> 3.9.0)
|
48
|
+
rspec-expectations (~> 3.9.0)
|
49
|
+
rspec-mocks (~> 3.9.0)
|
50
|
+
rspec-collection_matchers (1.2.0)
|
57
51
|
rspec-expectations (>= 2.99.0.beta1)
|
58
|
-
rspec-core (3.
|
59
|
-
rspec-support (~> 3.
|
60
|
-
rspec-expectations (3.
|
52
|
+
rspec-core (3.9.2)
|
53
|
+
rspec-support (~> 3.9.3)
|
54
|
+
rspec-expectations (3.9.1)
|
61
55
|
diff-lcs (>= 1.2.0, < 2.0)
|
62
|
-
rspec-support (~> 3.
|
63
|
-
rspec-mocks (3.
|
56
|
+
rspec-support (~> 3.9.0)
|
57
|
+
rspec-mocks (3.9.1)
|
64
58
|
diff-lcs (>= 1.2.0, < 2.0)
|
65
|
-
rspec-support (~> 3.
|
66
|
-
rspec-support (3.
|
67
|
-
rubocop (
|
68
|
-
jaro_winkler (~> 1.5.1)
|
59
|
+
rspec-support (~> 3.9.0)
|
60
|
+
rspec-support (3.9.3)
|
61
|
+
rubocop (1.22.3)
|
69
62
|
parallel (~> 1.10)
|
70
|
-
parser (>=
|
63
|
+
parser (>= 3.0.0.0)
|
71
64
|
rainbow (>= 2.2.2, < 4.0)
|
65
|
+
regexp_parser (>= 1.8, < 3.0)
|
66
|
+
rexml
|
67
|
+
rubocop-ast (>= 1.12.0, < 2.0)
|
72
68
|
ruby-progressbar (~> 1.7)
|
73
|
-
unicode-display_width (>= 1.4.0, <
|
74
|
-
|
75
|
-
|
69
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
70
|
+
rubocop-ast (1.13.0)
|
71
|
+
parser (>= 3.0.1.1)
|
72
|
+
ruby-progressbar (1.11.0)
|
73
|
+
simplecov (0.21.2)
|
76
74
|
docile (~> 1.1)
|
77
|
-
|
78
|
-
|
79
|
-
simplecov-html (0.
|
75
|
+
simplecov-html (~> 0.11)
|
76
|
+
simplecov_json_formatter (~> 0.1)
|
77
|
+
simplecov-html (0.12.3)
|
78
|
+
simplecov-lcov (0.8.0)
|
79
|
+
simplecov_json_formatter (0.1.3)
|
80
80
|
sqlite3 (1.4.1)
|
81
|
-
term-ansicolor (1.7.1)
|
82
|
-
tins (~> 1.0)
|
83
81
|
thor (0.20.3)
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
82
|
+
timecop (0.9.1)
|
83
|
+
tzinfo (2.0.4)
|
84
|
+
concurrent-ruby (~> 1.0)
|
85
|
+
unicode-display_width (2.1.0)
|
86
|
+
zeitwerk (2.5.1)
|
89
87
|
|
90
88
|
PLATFORMS
|
91
89
|
ruby
|
90
|
+
x86_64-darwin-19
|
92
91
|
|
93
92
|
DEPENDENCIES
|
94
93
|
active_record_data_loader!
|
95
94
|
appraisal
|
96
95
|
bundler (>= 1.16)
|
97
|
-
|
96
|
+
mysql2
|
98
97
|
pg
|
99
98
|
pry
|
100
|
-
rake (~>
|
99
|
+
rake (~> 13.0)
|
101
100
|
rspec (~> 3.0)
|
102
101
|
rspec-collection_matchers
|
103
102
|
rubocop
|
103
|
+
simplecov
|
104
|
+
simplecov-lcov
|
104
105
|
sqlite3
|
106
|
+
timecop
|
105
107
|
|
106
108
|
BUNDLED WITH
|
107
|
-
2.
|
109
|
+
2.2.31
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
#
|
1
|
+
# active_record_data_loader
|
2
2
|
|
3
|
-
[![Build Status](https://
|
3
|
+
[![Build Status](https://github.com/abeiderman/active_record_data_loader/actions/workflows/build.yml/badge.svg)](https://github.com/abeiderman/active_record_data_loader/actions/workflows/build.yml)
|
4
4
|
[![Coverage Status](https://coveralls.io/repos/github/abeiderman/active_record_data_loader/badge.svg?branch=master&service=github)](https://coveralls.io/github/abeiderman/active_record_data_loader?branch=master)
|
5
5
|
[![Maintainability](https://api.codeclimate.com/v1/badges/338904b3f7e8d19a3cb1/maintainability)](https://codeclimate.com/github/abeiderman/active_record_data_loader/maintainability)
|
6
6
|
|
@@ -10,6 +10,10 @@ Efficiently bulk load data for your ActiveRecord models with a simple DSL.
|
|
10
10
|
|
11
11
|
Load, performance, and stress tests often require setting up a realistic amount of data in your database. This gem is intended to help organize that data load and make it more maintainable than having a collection of SQL scripts.
|
12
12
|
|
13
|
+
#### How is this different from using _factory_bot_?
|
14
|
+
|
15
|
+
This gem is not a replacement for [factory_bot](https://github.com/thoughtbot/factory_bot). It solves a different use case. While _factory_bot_ is great for organizing test data and reducing duplication in your functional tests, _active_record_data_loader_ is focused around bulk loading data for performance tests. The purpose of _active_record_data_loader_ is loading large amounts of data as efficiently as possible while providing a DSL that helps with maintainability.
|
16
|
+
|
13
17
|
## Installation
|
14
18
|
|
15
19
|
Add this line to your application's Gemfile:
|
@@ -95,13 +99,13 @@ data_loader = ActiveRecordDataLoader.define do
|
|
95
99
|
m.column :currency, "CAD"
|
96
100
|
m.belongs_to :customer, eligible_set: -> { Customer.where(country: "CAN") }
|
97
101
|
end
|
98
|
-
|
102
|
+
|
99
103
|
model Order do |m|
|
100
104
|
m.count 25_000
|
101
105
|
m.column :currency, "MXN"
|
102
106
|
m.belongs_to :customer, eligible_set: -> { Customer.where(country: "MEX") }
|
103
107
|
end
|
104
|
-
|
108
|
+
|
105
109
|
model Order do |m|
|
106
110
|
m.count 50_000
|
107
111
|
m.column :currency, "USD"
|
@@ -144,7 +148,7 @@ data_loader = ActiveRecordDataLoader.define do
|
|
144
148
|
|
145
149
|
model Order do |m|
|
146
150
|
m.count 100_000
|
147
|
-
|
151
|
+
|
148
152
|
m.polymorphic :customer do |c|
|
149
153
|
c.model Person
|
150
154
|
c.model Business
|
@@ -168,7 +172,7 @@ data_loader = ActiveRecordDataLoader.define do
|
|
168
172
|
|
169
173
|
model Order do |m|
|
170
174
|
m.count 100_000
|
171
|
-
|
175
|
+
|
172
176
|
m.polymorphic :customer do |c|
|
173
177
|
c.model Person, weight: 2
|
174
178
|
c.model Business, weight: 1
|
@@ -193,7 +197,7 @@ data_loader = ActiveRecordDataLoader.define do
|
|
193
197
|
|
194
198
|
model Order do |m|
|
195
199
|
m.count 100_000
|
196
|
-
|
200
|
+
|
197
201
|
m.polymorphic :customer do |c|
|
198
202
|
c.model Person, weight: 2
|
199
203
|
c.model Business, weight: 1, eligible_set: -> { Business.where(country: "USA") }
|
@@ -204,6 +208,85 @@ end
|
|
204
208
|
data_loader.load_data
|
205
209
|
```
|
206
210
|
|
211
|
+
### Configuration options
|
212
|
+
|
213
|
+
You can define global configuration options like this:
|
214
|
+
|
215
|
+
```ruby
|
216
|
+
ActiveRecordDataLoader.configure do |c|
|
217
|
+
c.logger = ActiveSupport::Logger.new("my_file.log", level: :debug)
|
218
|
+
c.statement_timeout = "5min"
|
219
|
+
end
|
220
|
+
```
|
221
|
+
|
222
|
+
Or you can create a configuration object for the specific data loader instance rather than globally:
|
223
|
+
|
224
|
+
```ruby
|
225
|
+
config = ActiveRecordDataLoader::Configuration.new(
|
226
|
+
c.logger = ActiveSupport::Logger.new("my_file.log", level: :debug)
|
227
|
+
c.statement_timeout = "5min"
|
228
|
+
)
|
229
|
+
loader = ActiveRecordDataLoader.define(config) do
|
230
|
+
model Company do |m|
|
231
|
+
m.count 10
|
232
|
+
end
|
233
|
+
|
234
|
+
# ... more definitions
|
235
|
+
end
|
236
|
+
```
|
237
|
+
|
238
|
+
#### statement_timeout
|
239
|
+
|
240
|
+
This is currently only used for Postgres connections to adjust the `statement_timeout` value for the connection. The default is `2min`. Depending on the size of the batches you are loading and overall size of the tables you may need to increase this value:
|
241
|
+
|
242
|
+
```ruby
|
243
|
+
ActiveRecordDataLoader.configure do |c|
|
244
|
+
c.statement_timeout = "5min"
|
245
|
+
end
|
246
|
+
```
|
247
|
+
|
248
|
+
#### connection_factory
|
249
|
+
|
250
|
+
The `connection_factory` option accepts a lambda that should return a connection object whenever executed. If not specified, the default behavior is to retrieve a connection using `ActiveRecord::Base.connection`. You can configure it like this:
|
251
|
+
|
252
|
+
```ruby
|
253
|
+
ActiveRecordDataLoader.configure do |c|
|
254
|
+
c.connection_factory = -> { MyCustomConnectionHandler.open_connection }
|
255
|
+
end
|
256
|
+
```
|
257
|
+
|
258
|
+
#### output
|
259
|
+
|
260
|
+
The `output` option accepts either `:connection` or `:file`. The default behavior is `:connection` which means the data will be loaded into the database using the database connection.
|
261
|
+
|
262
|
+
If `:file` is specified, instead of the data being loaded into the database, a script file will be generated. This script file can then be executed manually to load the data. This can be helpful if you need to load the same data multiple times. For example if you are profiling different alternatives in your code and you want to see how each performs with a fully loaded database. In that case you would want to have the same data starting point for each alternative you evaluate. By generating the script file ahead of time, it would be significantly faster to load that data over and over by executing the existing script.
|
263
|
+
|
264
|
+
Here are some examples on how to use the `output` option:
|
265
|
+
|
266
|
+
```ruby
|
267
|
+
ActiveRecordDataLoader.configure do |c|
|
268
|
+
c.output = :connection # This is the default behavior
|
269
|
+
end
|
270
|
+
```
|
271
|
+
|
272
|
+
```ruby
|
273
|
+
ActiveRecordDataLoader.configure do |c|
|
274
|
+
c.output = :file # Outputs to a file with a default name
|
275
|
+
end
|
276
|
+
```
|
277
|
+
|
278
|
+
```ruby
|
279
|
+
ActiveRecordDataLoader.configure do |c|
|
280
|
+
c.output = { type: :file, filename: "./my_script.sql" } # Outputs to the provided file
|
281
|
+
end
|
282
|
+
```
|
283
|
+
|
284
|
+
When using the `:file` type with Postgres, the resulting script will have `\COPY` commands which reference CSV files that contain the data batches to be copied. The CSV files will be created along side the SQL script and will have a naming convention of using the table name and the rows range for the given batch. For example `./my_script_customers_1_to_1000.csv`. Each `\COPY` command in the SQL file will reference the corresponding CSV file so all you need to do is execute the SQL file using `psql`:
|
285
|
+
|
286
|
+
```bash
|
287
|
+
psql -h my-db-host -U my_user -f my_script.sql
|
288
|
+
```
|
289
|
+
|
207
290
|
## Development
|
208
291
|
|
209
292
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
@@ -220,4 +303,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
220
303
|
|
221
304
|
## Code of Conduct
|
222
305
|
|
223
|
-
Everyone interacting in the
|
306
|
+
Everyone interacting in the _active_record_data_loader_ project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/abeiderman/active_record_data_loader/blob/master/CODE_OF_CONDUCT.md).
|
data/Rakefile
CHANGED
@@ -3,10 +3,16 @@
|
|
3
3
|
require "bundler/gem_tasks"
|
4
4
|
require "rspec/core/rake_task"
|
5
5
|
require "rubocop/rake_task"
|
6
|
-
require "coveralls/rake/task"
|
7
6
|
|
8
7
|
RSpec::Core::RakeTask.new(:spec)
|
9
8
|
RuboCop::RakeTask.new(:rubocop)
|
10
|
-
Coveralls::RakeTask.new
|
11
9
|
|
12
10
|
task default: [:spec, :rubocop]
|
11
|
+
|
12
|
+
task :wait_for_test_db do
|
13
|
+
require "active_record_data_loader"
|
14
|
+
require "./spec/active_record_helper"
|
15
|
+
|
16
|
+
ActiveRecordHelper.wait_for_mysql
|
17
|
+
ActiveRecordHelper.wait_for_postgres
|
18
|
+
end
|
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
|
|
20
20
|
spec.metadata["source_code_uri"] = "https://github.com/abeiderman/active_record_data_loader"
|
21
21
|
else
|
22
22
|
raise "RubyGems 2.0 or newer is required to protect against " \
|
23
|
-
|
23
|
+
"public gem pushes."
|
24
24
|
end
|
25
25
|
|
26
26
|
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
@@ -30,18 +30,21 @@ Gem::Specification.new do |spec|
|
|
30
30
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
31
31
|
spec.require_paths = ["lib"]
|
32
32
|
|
33
|
-
spec.required_ruby_version = ">= 2.
|
33
|
+
spec.required_ruby_version = ">= 2.5.0"
|
34
34
|
|
35
|
-
spec.add_dependency "activerecord", ">=
|
35
|
+
spec.add_dependency "activerecord", ">= 5.0"
|
36
36
|
|
37
37
|
spec.add_development_dependency "appraisal"
|
38
38
|
spec.add_development_dependency "bundler", ">= 1.16"
|
39
|
-
spec.add_development_dependency "
|
39
|
+
spec.add_development_dependency "mysql2"
|
40
40
|
spec.add_development_dependency "pg"
|
41
41
|
spec.add_development_dependency "pry"
|
42
|
-
spec.add_development_dependency "rake", "~>
|
42
|
+
spec.add_development_dependency "rake", "~> 13.0"
|
43
43
|
spec.add_development_dependency "rspec", "~> 3.0"
|
44
44
|
spec.add_development_dependency "rspec-collection_matchers"
|
45
45
|
spec.add_development_dependency "rubocop"
|
46
|
+
spec.add_development_dependency "simplecov"
|
47
|
+
spec.add_development_dependency "simplecov-lcov"
|
46
48
|
spec.add_development_dependency "sqlite3"
|
49
|
+
spec.add_development_dependency "timecop"
|
47
50
|
end
|
data/config/database.yml
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
postgres:
|
2
2
|
adapter: "postgresql"
|
3
3
|
host: "127.0.0.1"
|
4
|
+
port: "2345"
|
4
5
|
database: "test"
|
5
6
|
username: "test"
|
6
7
|
password: "test"
|
@@ -8,3 +9,11 @@ postgres:
|
|
8
9
|
sqlite3:
|
9
10
|
adapter: "sqlite3"
|
10
11
|
database: ":memory:"
|
12
|
+
|
13
|
+
mysql:
|
14
|
+
adapter: "mysql2"
|
15
|
+
host: "127.0.0.1"
|
16
|
+
port: "3306"
|
17
|
+
database: "test"
|
18
|
+
username: "test"
|
19
|
+
password: "test"
|
data/docker-compose.yml
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
version: "3.9"
|
2
|
+
services:
|
3
|
+
postgres:
|
4
|
+
image: postgres:11
|
5
|
+
ports:
|
6
|
+
- "2345:5432"
|
7
|
+
environment:
|
8
|
+
- POSTGRES_USER=test
|
9
|
+
- POSTGRES_PASSWORD=test
|
10
|
+
mysql:
|
11
|
+
image: mysql:5
|
12
|
+
ports:
|
13
|
+
- "3306:3306"
|
14
|
+
environment:
|
15
|
+
- MYSQL_ROOT_PASSWORD=test
|
16
|
+
- MYSQL_USER=test
|
17
|
+
- MYSQL_PASSWORD=test
|
18
|
+
- MYSQL_DATABASE=test
|