pgsync 0.5.2 → 0.6.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: af75f9e9eb115a889d53b10ed89d8355e3ef111868b69eec31a025a8f22db27e
4
- data.tar.gz: 5da0d56267ac89f2ffc282e92275a91d3fb83d80fe969207329ec8ce1876472b
3
+ metadata.gz: 6c4a582f7fd5b997ba91247f2b57ad68aae7b5fad282c32dca873d75667922af
4
+ data.tar.gz: a7ae6518b84d28c8ad14786793b8d4257d898214b8071ccc6c91e9d4d144e316
5
5
  SHA512:
6
- metadata.gz: 9f9d78aebf02f75a5fee9413b56bba68ed97334b3134cef5c28f4b5a8a15cbab45e752cb73dcd88028e2b3b2b0fefb20ef9bd4abe0c92d35998a520b0029e961
7
- data.tar.gz: a2fdaee8ba32df378ed2538119817b7649fe134a33c0f6013d55d8e1cb76ae6b0a75d3dd10dff4872d0452bc2e41bb0024c5f276f16ed8f0d1c81b114574f757
6
+ metadata.gz: f008b6d7114e3f11395479de0e85006c5eb48681b13ab613e1468d20a99acf0121566fe5499e236d1e8b07fdd12acc2c3a99399daac3e3e99269efac5e6bd4e5
7
+ data.tar.gz: 536af357b17f35c7afb0e8efba5411a0ecbec67adbfe364d465a8831dd0e56d108055b1ccb55bc0203d92d9a3215a11d3a287f52e89b40b6526534ddfbc8371e
@@ -1,3 +1,40 @@
1
+ ## 0.6.1 (2020-06-07)
2
+
3
+ - Added Django and Laravel integrations
4
+
5
+ ## 0.6.0 (2020-06-07)
6
+
7
+ - Added messages for different column types and non-deferrable constraints
8
+ - Added support for wildcards to `--exclude`
9
+ - Improved `--overwrite` and `--preserve` options for foreign keys
10
+ - Improved output for schema sync
11
+ - Fixed `--overwrite` and `--preserve` options for multicolumn primary keys
12
+ - Fixed output for notices
13
+
14
+ Breaking
15
+
16
+ - Syncs shared tables instead of raising an error when tables missing in destination
17
+ - Raise an error when `--config` or `--db` option provided and config not found
18
+ - Removed deprecated options
19
+ - Dropped support for Postgres < 9.5
20
+
21
+ ## 0.5.5 (2020-05-13)
22
+
23
+ - Added `--jobs` option
24
+ - Added `--defer-constraints` option
25
+ - Added `--disable-user-triggers` option
26
+ - Added `--disable-integrity` option
27
+ - Improved error message for older libpq
28
+
29
+ ## 0.5.4 (2020-05-09)
30
+
31
+ - Fixed output for `--in-batches`
32
+
33
+ ## 0.5.3 (2020-04-03)
34
+
35
+ - Improved Postgres error messages
36
+ - Fixed behavior of wildcard without schema
37
+
1
38
  ## 0.5.2 (2020-03-27)
2
39
 
3
40
  - Added `--fail-fast` option
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2015-2019 Andrew Kane
3
+ Copyright (c) 2015-2020 Andrew Kane
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
data/README.md CHANGED
@@ -33,20 +33,26 @@ This creates `.pgsync.yml` for you to customize. We recommend checking this into
33
33
 
34
34
  ## How to Use
35
35
 
36
- Sync all tables
36
+ First, make sure your schema is set up in both databases. We recommend using a schema migration tool for this, but pgsync also provides a few [convenience methods](#schema). Once that’s done, you’re ready to sync data.
37
+
38
+ Sync tables
37
39
 
38
40
  ```sh
39
41
  pgsync
40
42
  ```
41
43
 
42
- **Note:** pgsync assumes your schema is setup in your `to` database. See the [schema section](#schema) if that’s not the case.
43
-
44
44
  Sync specific tables
45
45
 
46
46
  ```sh
47
47
  pgsync table1,table2
48
48
  ```
49
49
 
50
+ Works with wildcards as well
51
+
52
+ ```sh
53
+ pgsync "table*"
54
+ ```
55
+
50
56
  Sync specific rows (existing rows are overwritten)
51
57
 
52
58
  ```sh
@@ -65,13 +71,15 @@ Or truncate them
65
71
  pgsync products "where store_id = 1" --truncate
66
72
  ```
67
73
 
68
- ### Exclude Tables
74
+ ## Tables
75
+
76
+ Exclude specific tables
69
77
 
70
78
  ```sh
71
- pgsync --exclude users
79
+ pgsync --exclude table1,table2
72
80
  ```
73
81
 
74
- To always exclude, add to `.pgsync.yml`.
82
+ Add to `.pgsync.yml` to exclude by default
75
83
 
76
84
  ```yml
77
85
  exclude:
@@ -79,15 +87,17 @@ exclude:
79
87
  - table2
80
88
  ```
81
89
 
82
- For Rails, you probably want to exclude schema migrations and ActiveRecord metadata.
90
+ Sync tables from all schemas or specific schemas (by default, only the search path is synced)
83
91
 
84
- ```yml
85
- exclude:
86
- - schema_migrations
87
- - ar_internal_metadata
92
+ ```sh
93
+ pgsync --all-schemas
94
+ # or
95
+ pgsync --schemas public,other
96
+ # or
97
+ pgsync public.table1,other.table2
88
98
  ```
89
99
 
90
- ### Groups
100
+ ## Groups
91
101
 
92
102
  Define groups in `.pgsync.yml`:
93
103
 
@@ -104,6 +114,8 @@ And run:
104
114
  pgsync group1
105
115
  ```
106
116
 
117
+ ## Variables
118
+
107
119
  You can also use groups to sync a specific record and associated records in other tables.
108
120
 
109
121
  To get product `123` with its reviews, last 10 coupons, and store, use:
@@ -123,18 +135,14 @@ And run:
123
135
  pgsync product:123
124
136
  ```
125
137
 
126
- ### Schema
127
-
128
- **Note:** pgsync is designed to sync data. You should use a schema migration tool to manage schema changes. The methods in this section are provided for convenience but not recommended.
138
+ ## Schema
129
139
 
130
- Sync schema before the data
140
+ Sync schema before the data (this wipes out existing data)
131
141
 
132
142
  ```sh
133
143
  pgsync --schema-first
134
144
  ```
135
145
 
136
- **Note:** This wipes out existing data
137
-
138
146
  Specify tables
139
147
 
140
148
  ```sh
@@ -149,13 +157,9 @@ pgsync --schema-only
149
157
 
150
158
  pgsync does not try to sync Postgres extensions.
151
159
 
152
- ## Data Protection
153
-
154
- Always make sure your [connection is secure](https://ankane.org/postgres-sslmode-explained) when connecting to a database over a network you don’t fully trust. Your best option is to connect over SSH or a VPN. Another option is to use `sslmode=verify-full`. If you don’t do this, your database credentials can be compromised.
155
-
156
- ## Sensitive Information
160
+ ## Sensitive Data
157
161
 
158
- Prevent sensitive information like email addresses from leaving the remote server.
162
+ Prevent sensitive data like email addresses from leaving the remote server.
159
163
 
160
164
  Define rules in `.pgsync.yml`:
161
165
 
@@ -188,7 +192,61 @@ Options for replacement are:
188
192
  - `null`
189
193
  - `untouched`
190
194
 
191
- Rules starting with `unique_` require the table to have a primary key. `unique_phone` requires a numeric primary key.
195
+ Rules starting with `unique_` require the table to have a single column primary key. `unique_phone` requires a numeric primary key.
196
+
197
+ ## Foreign Keys
198
+
199
+ Foreign keys can make it difficult to sync data. Three options are:
200
+
201
+ 1. Manually specify the order of tables
202
+ 2. Use deferrable constraints
203
+ 3. Disable foreign key triggers, which can silently break referential integrity
204
+
205
+ When manually specifying the order, use `--jobs 1` so tables are synced one-at-a-time.
206
+
207
+ ```sh
208
+ pgsync table1,table2,table3 --jobs 1
209
+ ```
210
+
211
+ If your tables have [deferrable constraints](https://begriffs.com/posts/2017-08-27-deferrable-sql-constraints.html), use:
212
+
213
+ ```sh
214
+ pgsync --defer-constraints
215
+ ```
216
+
217
+ To disable foreign key triggers and potentially break referential integrity, use:
218
+
219
+ ```sh
220
+ pgsync --disable-integrity
221
+ ```
222
+
223
+ ## Triggers
224
+
225
+ Disable user triggers with:
226
+
227
+ ```sh
228
+ pgsync --disable-user-triggers
229
+ ```
230
+
231
+ ## Append-Only Tables
232
+
233
+ For extremely large, append-only tables, sync in batches.
234
+
235
+ ```sh
236
+ pgsync large_table --in-batches
237
+ ```
238
+
239
+ The script will resume where it left off when run again, making it great for backfills.
240
+
241
+ ## Connection Security
242
+
243
+ Always make sure your [connection is secure](https://ankane.org/postgres-sslmode-explained) when connecting to a database over a network you don’t fully trust. Your best option is to connect over SSH or a VPN. Another option is to use `sslmode=verify-full`. If you don’t do this, your database credentials can be compromised.
244
+
245
+ ## Safety
246
+
247
+ To keep you from accidentally overwriting production, the destination is limited to `localhost` or `127.0.0.1` by default.
248
+
249
+ To use another host, add `to_safe: true` to your `.pgsync.yml`.
192
250
 
193
251
  ## Multiple Databases
194
252
 
@@ -204,31 +262,50 @@ This creates `.pgsync-db2.yml` for you to edit. Specify a database in commands w
204
262
  pgsync --db db2
205
263
  ```
206
264
 
207
- ## Safety
265
+ ## Integrations
208
266
 
209
- To keep you from accidentally overwriting production, the destination is limited to `localhost` or `127.0.0.1` by default.
267
+ - [Django](#django)
268
+ - [Heroku](#heroku)
269
+ - [Laravel](#laravel)
270
+ - [Rails](#rails)
210
271
 
211
- To use another host, add `to_safe: true` to your `.pgsync.yml`.
272
+ ### Django
212
273
 
213
- ## Large Tables
274
+ If you run `pgsync --init` in a Django project, migrations will be excluded in `.pgsync.yml`.
214
275
 
215
- For extremely large tables, sync in batches.
276
+ ```yml
277
+ exclude:
278
+ - django_migrations
279
+ ```
216
280
 
217
- ```sh
218
- pgsync large_table --in-batches
281
+ ### Heroku
282
+
283
+ If you run `pgsync --init` in a Heroku project, the `from` database will be set in `.pgsync.yml`.
284
+
285
+ ```yml
286
+ from: $(heroku config:get DATABASE_URL)?sslmode=require
219
287
  ```
220
288
 
221
- The script will resume where it left off when run again, making it great for backfills.
289
+ ### Laravel
222
290
 
223
- ## Foreign Keys
291
+ If you run `pgsync --init` in a Laravel project, migrations will be excluded in `.pgsync.yml`.
224
292
 
225
- By default, tables are copied in parallel. If you use foreign keys, this can cause violations. You can specify tables to be copied serially with:
293
+ ```yml
294
+ exclude:
295
+ - migrations
296
+ ```
226
297
 
227
- ```sh
228
- pgsync group1 --debug
298
+ ### Rails
299
+
300
+ If you run `pgsync --init` in a Rails project, Active Record metadata and schema migrations will be excluded in `.pgsync.yml`.
301
+
302
+ ```yml
303
+ exclude:
304
+ - ar_internal_metadata
305
+ - schema_migrations
229
306
  ```
230
307
 
231
- ## Reference
308
+ ## Other Commands
232
309
 
233
310
  Help
234
311
 
@@ -242,6 +319,12 @@ Version
242
319
  pgsync --version
243
320
  ```
244
321
 
322
+ List tables
323
+
324
+ ```sh
325
+ pgsync --list
326
+ ```
327
+
245
328
  ## Scripts
246
329
 
247
330
  Use groups when possible to take advantage of parallelism.
data/config.yml CHANGED
@@ -20,6 +20,10 @@ to: postgres://localhost:5432/myapp_development
20
20
  # - table1
21
21
  # - table2
22
22
 
23
+ # sync specific schemas
24
+ # schemas:
25
+ # - public
26
+
23
27
  # protect sensitive information
24
28
  data_rules:
25
29
  email: unique_email
data/exe/pgsync CHANGED
@@ -1,9 +1,5 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- # disable Slop warning with Ruby 2.7
4
- # TODO remove when Slop > 4.7.0 is released
5
- $VERBOSE = nil
6
-
7
3
  # handle interrupts
8
4
  trap("SIGINT") { abort }
9
5
 
@@ -10,15 +10,19 @@ require "shellwords"
10
10
  require "tempfile"
11
11
  require "uri"
12
12
  require "yaml"
13
+ require "open3"
13
14
 
14
15
  # modules
15
16
  require "pgsync/utils"
16
17
  require "pgsync/client"
17
18
  require "pgsync/data_source"
18
19
  require "pgsync/init"
20
+ require "pgsync/schema_sync"
19
21
  require "pgsync/sync"
20
- require "pgsync/table_list"
22
+ require "pgsync/table"
21
23
  require "pgsync/table_sync"
24
+ require "pgsync/task"
25
+ require "pgsync/task_resolver"
22
26
  require "pgsync/version"
23
27
 
24
28
  module PgSync
@@ -4,73 +4,75 @@ module PgSync
4
4
 
5
5
  def initialize(args)
6
6
  @args = args
7
- $stderr.sync = true
7
+ output.sync = true
8
8
  end
9
9
 
10
- def perform(testing: true)
11
- opts = parse_args
10
+ def perform
11
+ result = Slop::Parser.new(slop_options).parse(@args)
12
+ arguments = result.arguments
13
+ options = result.to_h
12
14
 
13
- if opts.version?
15
+ raise Error, "Specify either --db or --config, not both" if options[:db] && options[:config]
16
+ raise Error, "Cannot use --overwrite with --in-batches" if options[:overwrite] && options[:in_batches]
17
+
18
+ if options[:version]
14
19
  log VERSION
15
- elsif opts.help?
16
- log opts
17
- # TODO remove deprecated conditions (last two)
18
- elsif opts.init? || opts.setup? || opts.arguments[0] == "setup"
19
- Init.new.perform(opts)
20
+ elsif options[:help]
21
+ log slop_options
22
+ elsif options[:init]
23
+ Init.new(arguments, options).perform
20
24
  else
21
- Sync.new.perform(opts)
25
+ Sync.new(arguments, options).perform
22
26
  end
23
- rescue Error, PG::ConnectionBad => e
24
- raise e if testing
25
- abort colorize(e.message, 31) # red
27
+ rescue => e
28
+ # Error, PG::ConnectionBad, Slop::Error
29
+ raise e if options && options[:debug]
30
+ abort colorize(e.message.strip, :red)
26
31
  end
27
32
 
28
33
  def self.start
29
- new(ARGV).perform(testing: false)
34
+ new(ARGV).perform
30
35
  end
31
36
 
32
37
  protected
33
38
 
34
- def parse_args
35
- Slop.parse(@args) do |o|
36
- o.banner = %{Usage:
37
- pgsync [options]
39
+ def slop_options
40
+ o = Slop::Options.new
41
+ o.banner = %{Usage:
42
+ pgsync [options]
38
43
 
39
44
  Options:}
40
- o.string "-d", "--db", "database"
41
- o.string "-t", "--tables", "tables to sync"
42
- o.string "-g", "--groups", "groups to sync"
43
- o.string "--schemas", "schemas to sync"
44
- o.string "--from", "source"
45
- o.string "--to", "destination"
46
- o.string "--where", "where", help: false
47
- o.integer "--limit", "limit", help: false
48
- o.string "--exclude", "exclude tables"
49
- o.string "--config", "config file"
50
- # TODO much better name for this option
51
- o.boolean "--to-safe", "accept danger", default: false
52
- o.boolean "--debug", "debug", default: false
53
- o.boolean "--list", "list", default: false
54
- o.boolean "--overwrite", "overwrite existing rows", default: false, help: false
55
- o.boolean "--preserve", "preserve existing rows", default: false
56
- o.boolean "--truncate", "truncate existing rows", default: false
57
- o.boolean "--schema-first", "schema first", default: false
58
- o.boolean "--schema-only", "schema only", default: false
59
- o.boolean "--all-schemas", "all schemas", default: false
60
- o.boolean "--no-rules", "do not apply data rules", default: false
61
- o.boolean "--no-sequences", "do not sync sequences", default: false
62
- o.boolean "--init", "init", default: false
63
- o.boolean "--setup", "setup", default: false, help: false
64
- o.boolean "--in-batches", "in batches", default: false, help: false
65
- o.integer "--batch-size", "batch size", default: 10000, help: false
66
- o.float "--sleep", "sleep", default: 0, help: false
67
- o.boolean "--fail-fast", "stop on the first failed table", default: false
68
- # o.array "--var", "pass a variable"
69
- o.boolean "-v", "--version", "print the version"
70
- o.boolean "-h", "--help", "prints help"
71
- end
72
- rescue Slop::Error => e
73
- raise Error, e.message
45
+ o.string "-d", "--db", "database"
46
+ o.string "-t", "--tables", "tables to sync"
47
+ o.string "-g", "--groups", "groups to sync"
48
+ o.integer "-j", "--jobs", "number of tables to sync at a time"
49
+ o.string "--schemas", "schemas to sync"
50
+ o.string "--from", "source"
51
+ o.string "--to", "destination"
52
+ o.string "--exclude", "exclude tables"
53
+ o.string "--config", "config file"
54
+ o.boolean "--to-safe", "accept danger", default: false
55
+ o.boolean "--debug", "debug", default: false
56
+ o.boolean "--list", "list", default: false
57
+ o.boolean "--overwrite", "overwrite existing rows", default: false, help: false
58
+ o.boolean "--preserve", "preserve existing rows", default: false
59
+ o.boolean "--truncate", "truncate existing rows", default: false
60
+ o.boolean "--schema-first", "schema first", default: false
61
+ o.boolean "--schema-only", "schema only", default: false
62
+ o.boolean "--all-schemas", "all schemas", default: false
63
+ o.boolean "--no-rules", "do not apply data rules", default: false
64
+ o.boolean "--no-sequences", "do not sync sequences", default: false
65
+ o.boolean "--init", "init", default: false
66
+ o.boolean "--in-batches", "in batches", default: false, help: false
67
+ o.integer "--batch-size", "batch size", default: 10000, help: false
68
+ o.float "--sleep", "sleep", default: 0, help: false
69
+ o.boolean "--fail-fast", "stop on the first failed table", default: false
70
+ o.boolean "--defer-constraints", "defer constraints", default: false
71
+ o.boolean "--disable-user-triggers", "disable non-system triggers", default: false
72
+ o.boolean "--disable-integrity", "disable foreign key triggers", default: false
73
+ o.boolean "-v", "--version", "print the version"
74
+ o.boolean "-h", "--help", "prints help"
75
+ o
74
76
  end
75
77
  end
76
78
  end