sequel-from_csv 0.1.2 → 0.2.0
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 +5 -5
- data/lib/sequel-from_csv.rb +2 -0
- data/lib/sequel/extensions/from_csv.rb +16 -3
- data/lib/sequel/plugins/from_csv.rb +43 -8
- metadata +89 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3706abc5bcbc730c436d702292e8a7ace38ad3419c73ae9deb82f6b6cc0e3b56
|
4
|
+
data.tar.gz: 759e60fa7eec0007d63df5eef240917dad0174ee9b86f5a4ebba5b7d8b8fb09e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8dfbd463ee485c63aba9e405d9b3fed23fa4578bf5ff9109d3521af5162dc531c8c6f3a4ea4a2be6480e2dd7737a43c53c23c9e1e0a667f0f3cf2903cc707574
|
7
|
+
data.tar.gz: f148140f6ad0c12deb8ec902e415cf5575f6226d7d617e2c5a2a67454a2b0598295a1a9dc3c82bf43d9b7f020eb853173fefb9eb9a134d18ecd1803efc6576ce
|
@@ -2,7 +2,21 @@ module Sequel
|
|
2
2
|
module Extensions
|
3
3
|
module FromCsv
|
4
4
|
|
5
|
-
# Finds all CSV files
|
5
|
+
# Finds all CSV files recursively within a directory and calls #seed_from_csv on their respective models
|
6
|
+
#
|
7
|
+
# Calling #seed_from_csv with a directory contaning:
|
8
|
+
# - artists.csv
|
9
|
+
# - artist/has_albums.csv
|
10
|
+
#
|
11
|
+
# Would be equivalent to calling:
|
12
|
+
# Artist.seed_from_csv "artists.csv"
|
13
|
+
# Artist::HasAlbum.seed_from_csv "artist/has_albums.csv"
|
14
|
+
#
|
15
|
+
# *Options:*
|
16
|
+
# :delete_missing :: whether to remove rows from the table that were not found in the CSV file
|
17
|
+
# :reset_sequence :: whether to update the primary key's sequence to reflect the max primary key value
|
18
|
+
#
|
19
|
+
# :reset_sequence only works on PostgreSQL tables that auto-increment their primary keys using sequences
|
6
20
|
def seed_from_csv directory, **opts
|
7
21
|
|
8
22
|
Dir.glob("#{directory}/**/*.csv").each do |filename|
|
@@ -22,7 +36,6 @@ module Sequel
|
|
22
36
|
end
|
23
37
|
|
24
38
|
end
|
25
|
-
|
26
39
|
end
|
27
|
-
Database.register_extension
|
40
|
+
Database.register_extension :from_csv, Extensions::FromCsv
|
28
41
|
end
|
@@ -3,17 +3,48 @@ require 'csv'
|
|
3
3
|
module Sequel
|
4
4
|
module Plugins
|
5
5
|
module FromCsv
|
6
|
+
|
7
|
+
class MissingDataException < StandardError; end
|
8
|
+
class MissingFieldException < StandardError; end
|
9
|
+
class NotYetImplementedException < StandardError; end
|
10
|
+
|
6
11
|
module ClassMethods
|
7
12
|
|
8
|
-
# Synchronizes a table's data with a CSV file
|
9
|
-
|
13
|
+
# Synchronizes a table's data with a CSV file. Returns self.
|
14
|
+
#
|
15
|
+
# The table being synchronized must contain exactly one primary key column, and the CSV file used
|
16
|
+
# must contain the primary key column as one of its fields.
|
17
|
+
#
|
18
|
+
# *Options:*
|
19
|
+
# :delete_missing :: whether to remove rows from the table that were not found in the CSV file
|
20
|
+
# :reset_sequence :: whether to update the primary key's sequence to reflect the max primary key value
|
21
|
+
#
|
22
|
+
# :reset_sequence only works on PostgreSQL tables that auto-increment their primary keys using sequences
|
23
|
+
#
|
24
|
+
# *Usage:*
|
25
|
+
# class Artist < Sequel::Model
|
26
|
+
# plugin :from_csv
|
27
|
+
# end
|
28
|
+
# Artist.seed_from_csv "seeds/artists.csv", reset_sequence: true
|
29
|
+
def seed_from_csv csv_path, delete_missing: false, reset_sequence: false
|
10
30
|
|
11
31
|
# Read the source CSV file
|
12
|
-
data = CSV.table csv_path
|
32
|
+
data = CSV.table csv_path, converters: :date_time
|
33
|
+
|
34
|
+
# Guard against CSV files that have headers but not data (to handle a quirk in Ruby's CSV parser)
|
35
|
+
if data.headers.empty?
|
36
|
+
raise MissingDataException, "CSV file #{csv_path} did not contain any data rows"
|
37
|
+
end
|
38
|
+
|
39
|
+
# Check that all primary key columns are present
|
40
|
+
pk = self.primary_key
|
41
|
+
if Array === pk
|
42
|
+
raise NotYetImplementedException, "Sequel::Plugins::FromCsv does not yet support composite primary keys."
|
43
|
+
end
|
13
44
|
|
14
45
|
# Ensure the ID column exists
|
15
|
-
unless data.
|
16
|
-
raise "CSV file #{csv_path} must contain
|
46
|
+
unless data.headers.include? pk
|
47
|
+
raise MissingFieldException, "CSV file #{csv_path} must contain a column named '#{pk}'"
|
17
48
|
end
|
18
49
|
|
19
50
|
self.db.transaction do
|
@@ -21,12 +52,12 @@ module Sequel
|
|
21
52
|
# UPSERT
|
22
53
|
data.each do |row|
|
23
54
|
row = row.to_h # Convert CSV::Row to Hash
|
24
|
-
self.dataset.insert_conflict(target:
|
55
|
+
self.dataset.insert_conflict(target: pk, update: row).insert row
|
25
56
|
end
|
26
57
|
|
27
58
|
# DELETE old rows
|
28
59
|
if delete_missing
|
29
|
-
self.exclude(
|
60
|
+
self.exclude(pk => data.map{|row| row[pk]}).delete
|
30
61
|
end
|
31
62
|
|
32
63
|
# Update the table's sequence
|
@@ -35,7 +66,7 @@ module Sequel
|
|
35
66
|
when :postgres
|
36
67
|
self.db.run <<~SQL
|
37
68
|
SELECT
|
38
|
-
setval(pg_get_serial_sequence('#{self.simple_table}', '
|
69
|
+
setval(pg_get_serial_sequence('#{self.simple_table}', '#{pk}'), greatest(max(#{pk}), 1), true)
|
39
70
|
FROM
|
40
71
|
#{self.simple_table}
|
41
72
|
SQL
|
@@ -44,9 +75,13 @@ module Sequel
|
|
44
75
|
|
45
76
|
end
|
46
77
|
|
78
|
+
# Should return itself
|
79
|
+
self
|
80
|
+
|
47
81
|
end
|
48
82
|
|
49
83
|
end
|
84
|
+
|
50
85
|
end
|
51
86
|
end
|
52
87
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sequel-from_csv
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kenaniah Cerny
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-11-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -38,6 +38,76 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pg
|
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: appraisal
|
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
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: minitest
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: minitest-hooks
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: minitest-reporters
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
41
111
|
- !ruby/object:Gem::Dependency
|
42
112
|
name: bundler
|
43
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,6 +136,20 @@ dependencies:
|
|
66
136
|
- - ">="
|
67
137
|
- !ruby/object:Gem::Version
|
68
138
|
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: pry
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
69
153
|
description:
|
70
154
|
email:
|
71
155
|
- kenaniah@gmail.com
|
@@ -73,6 +157,7 @@ executables: []
|
|
73
157
|
extensions: []
|
74
158
|
extra_rdoc_files: []
|
75
159
|
files:
|
160
|
+
- lib/sequel-from_csv.rb
|
76
161
|
- lib/sequel/extensions/from_csv.rb
|
77
162
|
- lib/sequel/plugins/from_csv.rb
|
78
163
|
homepage: https://github.com/kenaniah/sequel-from_csv
|
@@ -86,7 +171,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
86
171
|
requirements:
|
87
172
|
- - ">="
|
88
173
|
- !ruby/object:Gem::Version
|
89
|
-
version:
|
174
|
+
version: 2.3.0
|
90
175
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
91
176
|
requirements:
|
92
177
|
- - ">="
|
@@ -94,7 +179,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
94
179
|
version: '0'
|
95
180
|
requirements: []
|
96
181
|
rubyforge_project:
|
97
|
-
rubygems_version: 2.6
|
182
|
+
rubygems_version: 2.7.6
|
98
183
|
signing_key:
|
99
184
|
specification_version: 4
|
100
185
|
summary: A simple way to seed and synchronize table data using CSV files
|