pgsync 0.3.4 → 0.3.5
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of pgsync might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +26 -5
- data/config.yml +1 -0
- data/lib/pgsync.rb +29 -23
- data/lib/pgsync/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: aba5139d6101c73512853da24762c38308f83b00
|
4
|
+
data.tar.gz: b9dda9275f5faf6a70cafebfba723d1eb96f6b09
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 08ae766aff0f46b73579f00d3ca3a72c7a27a2c25ce6d89f8ad271c1d4558a195d71eb367a3b9096b3d6896510e321bd017a81f3da7821818d6849b7e871e463
|
7
|
+
data.tar.gz: 0ad9116bd57ffbf6cc594146db0aa9d4ea414351331e0fc7cffb66e9e8eb934db266c9e266cafc2bdb0da1c5fb87ff3dcd737ee72e7622e0e321a552ada2c1a8
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -70,11 +70,12 @@ exclude:
|
|
70
70
|
- table2
|
71
71
|
```
|
72
72
|
|
73
|
-
For Rails, you probably want to exclude schema migrations.
|
73
|
+
For Rails, you probably want to exclude schema migrations and ActiveRecord metadata.
|
74
74
|
|
75
75
|
```yml
|
76
76
|
exclude:
|
77
77
|
- schema_migrations
|
78
|
+
- ar_internal_metadata
|
78
79
|
```
|
79
80
|
|
80
81
|
### Groups
|
@@ -181,6 +182,30 @@ To keep you from accidentally overwriting production, the destination is limited
|
|
181
182
|
|
182
183
|
To use another host, add `to_safe: true` to your `.pgsync.yml`.
|
183
184
|
|
185
|
+
## Large Tables
|
186
|
+
|
187
|
+
For extremely large tables, sync in batches.
|
188
|
+
|
189
|
+
```sh
|
190
|
+
pgsync large_table --in-batches
|
191
|
+
```
|
192
|
+
|
193
|
+
The script will resume where it left off when run again, making it great for backfills.
|
194
|
+
|
195
|
+
## Reference
|
196
|
+
|
197
|
+
Help
|
198
|
+
|
199
|
+
```sh
|
200
|
+
pgsync --help
|
201
|
+
```
|
202
|
+
|
203
|
+
Version
|
204
|
+
|
205
|
+
```sh
|
206
|
+
pgsync --version
|
207
|
+
```
|
208
|
+
|
184
209
|
## Setup Scripts
|
185
210
|
|
186
211
|
Use groups when possible to take advantage of parallelism.
|
@@ -212,10 +237,6 @@ gem specific_install ankane/pgsync
|
|
212
237
|
|
213
238
|
Inspired by [heroku-pg-transfer](https://github.com/ddollar/heroku-pg-transfer).
|
214
239
|
|
215
|
-
## TODO
|
216
|
-
|
217
|
-
- Support for schemas other than `public`
|
218
|
-
|
219
240
|
## Contributing
|
220
241
|
|
221
242
|
Everyone is encouraged to help improve this project. Here are a few ways you can help:
|
data/config.yml
CHANGED
data/lib/pgsync.rb
CHANGED
@@ -8,6 +8,7 @@ require "parallel"
|
|
8
8
|
require "multiprocessing"
|
9
9
|
require "fileutils"
|
10
10
|
require "tempfile"
|
11
|
+
require "cgi"
|
11
12
|
|
12
13
|
module URI
|
13
14
|
class POSTGRESQL < Generic
|
@@ -73,13 +74,17 @@ module PgSync
|
|
73
74
|
if opts[:setup]
|
74
75
|
setup(db_config_file(args[0]) || config_file || ".pgsync.yml")
|
75
76
|
else
|
77
|
+
if args.size > 2
|
78
|
+
abort "Usage:\n pgsync [options]"
|
79
|
+
end
|
80
|
+
|
76
81
|
source = parse_source(opts[:from])
|
77
82
|
abort "No source" unless source
|
78
|
-
source_uri = parse_uri(source)
|
83
|
+
source_uri, from_schema = parse_uri(source)
|
79
84
|
|
80
85
|
destination = parse_source(opts[:to])
|
81
86
|
abort "No destination" unless destination
|
82
|
-
destination_uri = parse_uri(destination)
|
87
|
+
destination_uri, to_schema = parse_uri(destination)
|
83
88
|
abort "Danger! Add `to_safe: true` to `.pgsync.yml` if the destination is not localhost or 127.0.0.1" unless %(localhost 127.0.0.1).include?(destination_uri.host) || opts[:to_safe]
|
84
89
|
|
85
90
|
print_uri("From", source_uri)
|
@@ -88,7 +93,7 @@ module PgSync
|
|
88
93
|
from_uri = source_uri
|
89
94
|
to_uri = destination_uri
|
90
95
|
|
91
|
-
tables = table_list(args, opts, from_uri)
|
96
|
+
tables = table_list(args, opts, from_uri, from_schema)
|
92
97
|
|
93
98
|
if opts[:schema_only]
|
94
99
|
log "* Dumping schema"
|
@@ -103,7 +108,7 @@ module PgSync
|
|
103
108
|
else
|
104
109
|
with_connection(to_uri, timeout: 3) do |conn|
|
105
110
|
tables.keys.each do |table|
|
106
|
-
unless table_exists?(conn, table,
|
111
|
+
unless table_exists?(conn, table, to_schema)
|
107
112
|
abort "Table does not exist in destination: #{table}"
|
108
113
|
end
|
109
114
|
end
|
@@ -117,7 +122,7 @@ module PgSync
|
|
117
122
|
end
|
118
123
|
else
|
119
124
|
in_parallel(tables) do |table, table_opts|
|
120
|
-
sync_table(table, opts.merge(table_opts), from_uri, to_uri)
|
125
|
+
sync_table(table, opts.merge(table_opts), from_uri, to_uri, from_schema, to_schema)
|
121
126
|
end
|
122
127
|
|
123
128
|
log_completed(start_time)
|
@@ -129,15 +134,15 @@ module PgSync
|
|
129
134
|
|
130
135
|
protected
|
131
136
|
|
132
|
-
def sync_table(table, opts, from_uri, to_uri)
|
137
|
+
def sync_table(table, opts, from_uri, to_uri, from_schema, to_schema)
|
133
138
|
time =
|
134
139
|
benchmark do
|
135
140
|
with_connection(from_uri) do |from_connection|
|
136
141
|
with_connection(to_uri) do |to_connection|
|
137
142
|
bad_fields = opts[:no_rules] ? [] : config["data_rules"]
|
138
143
|
|
139
|
-
from_fields = columns(from_connection, table,
|
140
|
-
to_fields = columns(to_connection, table,
|
144
|
+
from_fields = columns(from_connection, table, from_schema)
|
145
|
+
to_fields = columns(to_connection, table, to_schema)
|
141
146
|
shared_fields = to_fields & from_fields
|
142
147
|
extra_fields = to_fields - from_fields
|
143
148
|
missing_fields = from_fields - to_fields
|
@@ -177,7 +182,7 @@ module PgSync
|
|
177
182
|
|
178
183
|
copy_to_command = "COPY (SELECT #{copy_fields} FROM #{table}#{sql_clause}) TO STDOUT"
|
179
184
|
if opts[:in_batches]
|
180
|
-
primary_key = self.primary_key(from_connection, table,
|
185
|
+
primary_key = self.primary_key(from_connection, table, from_schema)
|
181
186
|
abort "No primary key" unless primary_key
|
182
187
|
|
183
188
|
from_max_id = max_id(from_connection, table, primary_key, sql_clause)
|
@@ -218,7 +223,7 @@ module PgSync
|
|
218
223
|
end
|
219
224
|
end
|
220
225
|
elsif !opts[:truncate] && (opts[:overwrite] || opts[:preserve] || !sql_clause.empty?)
|
221
|
-
primary_key = self.primary_key(
|
226
|
+
primary_key = self.primary_key(to_connection, table, to_schema)
|
222
227
|
abort "No primary key" unless primary_key
|
223
228
|
|
224
229
|
temp_table = "pgsync_#{rand(1_000_000_000)}"
|
@@ -497,7 +502,8 @@ Options:}
|
|
497
502
|
uri.host ||= "localhost"
|
498
503
|
uri.port ||= 5432
|
499
504
|
uri.path = "/#{uri.path}" if uri.path && uri.path[0] != "/"
|
500
|
-
uri
|
505
|
+
schema = ((uri.query && CGI::parse(uri.query)["schema"]) || ["public"])[0]
|
506
|
+
[uri, schema]
|
501
507
|
end
|
502
508
|
|
503
509
|
def print_uri(prefix, uri)
|
@@ -562,22 +568,22 @@ Options:}
|
|
562
568
|
end
|
563
569
|
end
|
564
570
|
|
565
|
-
def add_tables(tables, t, id, boom, from_uri)
|
571
|
+
def add_tables(tables, t, id, boom, from_uri, from_schema)
|
566
572
|
t.each do |table|
|
567
573
|
sql = nil
|
568
574
|
if table.is_a?(Array)
|
569
575
|
table, sql = table
|
570
576
|
end
|
571
|
-
add_table(tables, table, id, boom || sql, from_uri)
|
577
|
+
add_table(tables, table, id, boom || sql, from_uri, from_schema)
|
572
578
|
end
|
573
579
|
end
|
574
580
|
|
575
|
-
def add_table(tables, table, id, boom, from_uri, wildcard = false)
|
581
|
+
def add_table(tables, table, id, boom, from_uri, from_schema, wildcard = false)
|
576
582
|
if table.include?("*") && !wildcard
|
577
583
|
regex = Regexp.new('\A' + Regexp.escape(table).gsub('\*','[^\.]*') + '\z')
|
578
|
-
t2 = with_connection(from_uri) { |conn| self.tables(conn,
|
584
|
+
t2 = with_connection(from_uri) { |conn| self.tables(conn, from_schema) }.select { |t| regex.match(t) }
|
579
585
|
t2.each do |table|
|
580
|
-
add_table(tables, table, id, boom, from_uri, true)
|
586
|
+
add_table(tables, table, id, boom, from_uri, from_schema, true)
|
581
587
|
end
|
582
588
|
else
|
583
589
|
tables[table] = {}
|
@@ -585,7 +591,7 @@ Options:}
|
|
585
591
|
end
|
586
592
|
end
|
587
593
|
|
588
|
-
def table_list(args, opts, from_uri)
|
594
|
+
def table_list(args, opts, from_uri, from_schema)
|
589
595
|
tables = nil
|
590
596
|
|
591
597
|
if opts[:groups]
|
@@ -594,7 +600,7 @@ Options:}
|
|
594
600
|
specified_groups.map do |tag|
|
595
601
|
group, id = tag.split(":", 2)
|
596
602
|
if (t = (config["groups"] || {})[group])
|
597
|
-
add_tables(tables, t, id, args[1], from_uri)
|
603
|
+
add_tables(tables, t, id, args[1], from_uri, from_schema)
|
598
604
|
else
|
599
605
|
abort "Group not found: #{group}"
|
600
606
|
end
|
@@ -605,7 +611,7 @@ Options:}
|
|
605
611
|
tables ||= Hash.new { |hash, key| hash[key] = {} }
|
606
612
|
to_arr(opts[:tables]).each do |tag|
|
607
613
|
table, id = tag.split(":", 2)
|
608
|
-
add_table(tables, table, id, args[1], from_uri)
|
614
|
+
add_table(tables, table, id, args[1], from_uri, from_schema)
|
609
615
|
end
|
610
616
|
end
|
611
617
|
|
@@ -616,18 +622,18 @@ Options:}
|
|
616
622
|
specified_groups.map do |tag|
|
617
623
|
group, id = tag.split(":", 2)
|
618
624
|
if (t = (config["groups"] || {})[group])
|
619
|
-
add_tables(tables, t, id, args[1], from_uri)
|
625
|
+
add_tables(tables, t, id, args[1], from_uri, from_schema)
|
620
626
|
else
|
621
|
-
add_table(tables, group, id, args[1], from_uri)
|
627
|
+
add_table(tables, group, id, args[1], from_uri, from_schema)
|
622
628
|
end
|
623
629
|
end
|
624
630
|
end
|
625
631
|
|
626
632
|
with_connection(from_uri, timeout: 3) do |conn|
|
627
|
-
tables ||= Hash[(self.tables(conn,
|
633
|
+
tables ||= Hash[(self.tables(conn, from_schema) - to_arr(opts[:exclude])).map { |k| [k, {}] }]
|
628
634
|
|
629
635
|
tables.keys.each do |table|
|
630
|
-
unless table_exists?(conn, table,
|
636
|
+
unless table_exists?(conn, table, from_schema)
|
631
637
|
abort "Table does not exist in source: #{table}"
|
632
638
|
end
|
633
639
|
end
|
data/lib/pgsync/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pgsync
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Kane
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-07-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: slop
|