strong_migrations 0.2.2 → 0.2.3
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/CHANGELOG.md +6 -0
- data/CONTRIBUTING.md +45 -0
- data/LICENSE.txt +1 -1
- data/README.md +12 -5
- data/lib/strong_migrations.rb +11 -3
- data/lib/strong_migrations/alphabetize_columns.rb +11 -0
- data/lib/strong_migrations/migration.rb +8 -5
- data/lib/strong_migrations/railtie.rb +4 -0
- data/lib/strong_migrations/version.rb +1 -1
- data/lib/tasks/strong_migrations.rake +5 -15
- metadata +11 -13
- data/.gitignore +0 -9
- data/.travis.yml +0 -20
- data/Gemfile +0 -5
- data/Rakefile +0 -11
- data/strong_migrations.gemspec +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: fe026b71dc38ab1cc40189ff8eb858baa45ec0778bd4dd640cff57349aa067ea
|
4
|
+
data.tar.gz: 28698d9bc1804389fc4e1fdb9e9a3ae9499cc490b15bda953f312fe434a6aa41
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3fe33582e8f6f4c0aced4f162704a9810e044e11e115ac1813892750474c118a33f0fb2ee19883d4dce98bfc6862786eaaf1c7862b4fd3398c2bb032010316fb
|
7
|
+
data.tar.gz: 0e5bcf7c1a42dcebe09a5f249fd2cb063549c1617d8a161ae915e882ab30e7f9a72b19b38407f5a526b59174cf04bcfa04c790888b7ce069c58c5cf7116faf00
|
data/CHANGELOG.md
CHANGED
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# Contributing
|
2
|
+
|
3
|
+
First, thanks for wanting to contribute. You’re awesome! :heart:
|
4
|
+
|
5
|
+
## Questions
|
6
|
+
|
7
|
+
Use [Stack Overflow](https://stackoverflow.com/) with the tag `strong-migrations`.
|
8
|
+
|
9
|
+
## Feature Requests
|
10
|
+
|
11
|
+
Create an issue. Start the title with `[Idea]`.
|
12
|
+
|
13
|
+
## Issues
|
14
|
+
|
15
|
+
Think you’ve discovered an issue?
|
16
|
+
|
17
|
+
1. Search existing issues to see if it’s been reported.
|
18
|
+
2. Try the `master` branch to make sure it hasn’t been fixed.
|
19
|
+
|
20
|
+
```rb
|
21
|
+
gem "strong_migrations", github: "ankane/strong_migrations"
|
22
|
+
```
|
23
|
+
|
24
|
+
If the above steps don’t help, create an issue. Include:
|
25
|
+
|
26
|
+
- Detailed steps to reproduce
|
27
|
+
- Complete backtraces for exceptions
|
28
|
+
|
29
|
+
## Pull Requests
|
30
|
+
|
31
|
+
Fork the project and create a pull request. A few tips:
|
32
|
+
|
33
|
+
- Keep changes to a minimum. If you have multiple features or fixes, submit multiple pull requests.
|
34
|
+
- Follow the existing style. The code should read like it’s written by a single person.
|
35
|
+
- Add one or more tests if possible. Make sure existing tests pass with:
|
36
|
+
|
37
|
+
```sh
|
38
|
+
bundle exec rake test
|
39
|
+
```
|
40
|
+
|
41
|
+
Feel free to open an issue to get feedback on your idea before spending too much time on it.
|
42
|
+
|
43
|
+
---
|
44
|
+
|
45
|
+
This contributing guide is released under [CCO](https://creativecommons.org/publicdomain/zero/1.0/) (public domain). Use it for your own project without attribution.
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -16,7 +16,7 @@ gem 'strong_migrations'
|
|
16
16
|
|
17
17
|
## How It Works
|
18
18
|
|
19
|
-
Strong Migrations detects potentially dangerous operations in migrations, prevents them from running, and
|
19
|
+
Strong Migrations detects potentially dangerous operations in migrations, prevents them from running by default, and provides instructions on safer ways to do what you want.
|
20
20
|
|
21
21
|
```
|
22
22
|
__ __ _____ _______ _
|
@@ -45,6 +45,7 @@ The following operations can cause downtime or errors:
|
|
45
45
|
- adding a column with a non-null default value to an existing table
|
46
46
|
- removing a column
|
47
47
|
- changing the type of a column
|
48
|
+
- setting a `NOT NULL` constraint with a default value
|
48
49
|
- renaming a column
|
49
50
|
- renaming a table
|
50
51
|
- adding an index non-concurrently (Postgres only)
|
@@ -75,6 +76,8 @@ class AddSomeColumnToUsers < ActiveRecord::Migration[5.1]
|
|
75
76
|
end
|
76
77
|
```
|
77
78
|
|
79
|
+
Don’t backfill existing rows in this migration, as it can cause downtime. See the next section for how to do it safely.
|
80
|
+
|
78
81
|
### Backfilling data
|
79
82
|
|
80
83
|
To backfill data, use the Rails console or a separate migration with `disable_ddl_transaction!`. Avoid backfilling in a transaction, especially one that alters a table. See [this great article](https://wework.github.io/data/2015/11/05/add-columns-with-default-values-to-large-tables-in-rails-postgres/) on why.
|
@@ -166,9 +169,9 @@ class AddSomeIndexToUsers < ActiveRecord::Migration[5.1]
|
|
166
169
|
end
|
167
170
|
```
|
168
171
|
|
169
|
-
If you forget `disable_ddl_transaction!`, the migration will fail.
|
172
|
+
If you forget `disable_ddl_transaction!`, the migration will fail. Also, note that indexes on new tables (those created in the same migration) don’t require this.
|
170
173
|
|
171
|
-
|
174
|
+
Check out [this gem](https://github.com/ankane/gindex) to quickly generate index migrations without memorizing the syntax.
|
172
175
|
|
173
176
|
### Adding a json column (Postgres)
|
174
177
|
|
@@ -261,7 +264,7 @@ StrongMigrations.auto_analyze = true
|
|
261
264
|
|
262
265
|
## Lock Timeout (Postgres)
|
263
266
|
|
264
|
-
It’s a good idea to set a lock timeout for the database user that runs migrations. This way, if migrations can’t acquire a lock in a timely manner, other statements won’t be stuck behind it.
|
267
|
+
It’s a good idea to set a lock timeout for the database user that runs migrations. This way, if migrations can’t acquire a lock in a timely manner, other statements won’t be stuck behind it. Here’s a great explanation of [how lock queues work](https://www.citusdata.com/blog/2018/02/15/when-postgresql-blocks/).
|
265
268
|
|
266
269
|
```sql
|
267
270
|
ALTER ROLE myuser SET lock_timeout = '10s';
|
@@ -269,9 +272,13 @@ ALTER ROLE myuser SET lock_timeout = '10s';
|
|
269
272
|
|
270
273
|
There’s also [a gem](https://github.com/gocardless/activerecord-safer_migrations) you can use for this.
|
271
274
|
|
275
|
+
## Bigint Primary Keys (Postgres & MySQL)
|
276
|
+
|
277
|
+
Rails 5.1+ uses `bigint` for primary keys to keep you from running out of ids. To get this in earlier versions of Rails, check out [this gem](https://github.com/Shopify/rails-bigint-primarykey).
|
278
|
+
|
272
279
|
## Additional Reading
|
273
280
|
|
274
|
-
- [Rails Migrations with No Downtime](
|
281
|
+
- [Rails Migrations with No Downtime](https://pedro.herokuapp.com/past/2011/7/13/rails_migrations_with_no_downtime/)
|
275
282
|
- [Safe Operations For High Volume PostgreSQL](https://www.braintreepayments.com/blog/safe-operations-for-high-volume-postgresql/)
|
276
283
|
|
277
284
|
## Credits
|
data/lib/strong_migrations.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
require "active_support"
|
2
|
-
|
2
|
+
|
3
3
|
require "strong_migrations/database_tasks"
|
4
|
-
require "strong_migrations/unsafe_migration"
|
5
4
|
require "strong_migrations/migration"
|
6
5
|
require "strong_migrations/railtie" if defined?(Rails)
|
6
|
+
require "strong_migrations/unsafe_migration"
|
7
|
+
require "strong_migrations/version"
|
7
8
|
|
8
9
|
module StrongMigrations
|
9
10
|
class << self
|
@@ -122,7 +123,14 @@ Otherwise, remove the option.",
|
|
122
123
|
execute:
|
123
124
|
"The strong_migrations gem does not support inspecting what happens inside an
|
124
125
|
execute call, so cannot help you here. Please make really sure that what
|
125
|
-
you're doing is safe before proceeding, then wrap it in a safety_assured { ... } block."
|
126
|
+
you're doing is safe before proceeding, then wrap it in a safety_assured { ... } block.",
|
127
|
+
|
128
|
+
change_column_null:
|
129
|
+
"The last argument replaces existing NULLs with another value.
|
130
|
+
This runs a single UPDATE query, which can cause downtime.
|
131
|
+
Backfill NULLs manually in batches instead.
|
132
|
+
|
133
|
+
More info: https://github.com/ankane/strong_migrations#backfilling-data"
|
126
134
|
}
|
127
135
|
end
|
128
136
|
|
@@ -57,6 +57,7 @@ module StrongMigrations
|
|
57
57
|
when :create_table
|
58
58
|
options = args[1] || {}
|
59
59
|
raise_error :create_table if options[:force]
|
60
|
+
(@new_tables ||= []) << args[0].to_s
|
60
61
|
when :add_reference
|
61
62
|
options = args[2] || {}
|
62
63
|
index_value = options.fetch(:index, ActiveRecord::VERSION::MAJOR >= 5 ? true : false)
|
@@ -65,16 +66,18 @@ module StrongMigrations
|
|
65
66
|
end
|
66
67
|
when :execute
|
67
68
|
raise_error :execute
|
69
|
+
when :change_column_null
|
70
|
+
null = args[2]
|
71
|
+
default = args[3]
|
72
|
+
if !null && !default.nil?
|
73
|
+
raise_error :change_column_null
|
74
|
+
end
|
68
75
|
end
|
69
76
|
end
|
70
77
|
|
71
|
-
if method == :create_table
|
72
|
-
(@new_tables ||= []) << args[0].to_s
|
73
|
-
end
|
74
|
-
|
75
78
|
result = super
|
76
79
|
|
77
|
-
if StrongMigrations.auto_analyze && postgresql? && method == :add_index
|
80
|
+
if StrongMigrations.auto_analyze && @direction == :up && postgresql? && method == :add_index
|
78
81
|
connection.execute "ANALYZE VERBOSE #{connection.quote_table_name(args[0])}"
|
79
82
|
end
|
80
83
|
|
@@ -5,6 +5,10 @@ module StrongMigrations
|
|
5
5
|
class Railtie < Rails::Railtie
|
6
6
|
rake_tasks do
|
7
7
|
load "tasks/strong_migrations.rake"
|
8
|
+
|
9
|
+
["db:drop", "db:reset", "db:schema:load", "db:structure:load"].each do |t|
|
10
|
+
Rake::Task[t].enhance ["strong_migrations:safety_assured"]
|
11
|
+
end
|
8
12
|
end
|
9
13
|
end
|
10
14
|
end
|
@@ -10,21 +10,11 @@ namespace :strong_migrations do
|
|
10
10
|
$stderr.puts "Dumping schema"
|
11
11
|
ActiveRecord::Base.logger.level = Logger::INFO
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
def columns(*args)
|
18
|
-
old_columns(*args).sort_by(&:name)
|
19
|
-
end
|
20
|
-
|
21
|
-
def extensions(*args)
|
22
|
-
old_extensions(*args).sort
|
23
|
-
end
|
13
|
+
require "strong_migrations/alphabetize_columns"
|
14
|
+
ActiveRecord::Base.connection.class.prepend StrongMigrations::AlphabetizeColumns
|
15
|
+
if ActiveRecord::ConnectionAdapters.const_defined?('PostGISAdapter')
|
16
|
+
ActiveRecord::ConnectionAdapters::PostGISAdapter.prepend StrongMigrations::AlphabetizeColumns
|
24
17
|
end
|
18
|
+
ActiveRecord::ConnectionAdapters::AbstractAdapter.prepend StrongMigrations::AlphabetizeColumns
|
25
19
|
end
|
26
20
|
end
|
27
|
-
|
28
|
-
["db:drop", "db:reset", "db:schema:load", "db:structure:load"].each do |t|
|
29
|
-
Rake::Task[t].enhance ["strong_migrations:safety_assured"]
|
30
|
-
end
|
metadata
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: strong_migrations
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
+
- Andrew Kane
|
7
8
|
- Bob Remeika
|
8
9
|
- David Waller
|
9
|
-
- Andrew Kane
|
10
10
|
autorequire:
|
11
|
-
bindir:
|
11
|
+
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2018-
|
13
|
+
date: 2018-07-23 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|
@@ -84,29 +84,27 @@ dependencies:
|
|
84
84
|
version: '1'
|
85
85
|
description:
|
86
86
|
email:
|
87
|
-
- bob.remeika@gmail.com
|
88
87
|
- andrew@chartkick.com
|
88
|
+
- bob.remeika@gmail.com
|
89
89
|
executables: []
|
90
90
|
extensions: []
|
91
91
|
extra_rdoc_files: []
|
92
92
|
files:
|
93
|
-
- ".gitignore"
|
94
|
-
- ".travis.yml"
|
95
93
|
- CHANGELOG.md
|
96
|
-
-
|
94
|
+
- CONTRIBUTING.md
|
97
95
|
- LICENSE.txt
|
98
96
|
- README.md
|
99
|
-
- Rakefile
|
100
97
|
- lib/strong_migrations.rb
|
98
|
+
- lib/strong_migrations/alphabetize_columns.rb
|
101
99
|
- lib/strong_migrations/database_tasks.rb
|
102
100
|
- lib/strong_migrations/migration.rb
|
103
101
|
- lib/strong_migrations/railtie.rb
|
104
102
|
- lib/strong_migrations/unsafe_migration.rb
|
105
103
|
- lib/strong_migrations/version.rb
|
106
104
|
- lib/tasks/strong_migrations.rake
|
107
|
-
- strong_migrations.gemspec
|
108
105
|
homepage: https://github.com/ankane/strong_migrations
|
109
|
-
licenses:
|
106
|
+
licenses:
|
107
|
+
- MIT
|
110
108
|
metadata: {}
|
111
109
|
post_install_message:
|
112
110
|
rdoc_options: []
|
@@ -116,7 +114,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
116
114
|
requirements:
|
117
115
|
- - ">="
|
118
116
|
- !ruby/object:Gem::Version
|
119
|
-
version: '
|
117
|
+
version: '2.2'
|
120
118
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
119
|
requirements:
|
122
120
|
- - ">="
|
@@ -124,7 +122,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
124
122
|
version: '0'
|
125
123
|
requirements: []
|
126
124
|
rubyforge_project:
|
127
|
-
rubygems_version: 2.
|
125
|
+
rubygems_version: 2.7.7
|
128
126
|
signing_key:
|
129
127
|
specification_version: 4
|
130
128
|
summary: Catch unsafe migrations at dev time
|
data/.gitignore
DELETED
data/.travis.yml
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
rvm:
|
3
|
-
- 2.4.1
|
4
|
-
gemfile:
|
5
|
-
- Gemfile
|
6
|
-
- test/gemfiles/activerecord50.gemfile
|
7
|
-
- test/gemfiles/activerecord42.gemfile
|
8
|
-
script: bundle exec rake test
|
9
|
-
before_script:
|
10
|
-
- psql -c 'create database strong_migrations_test;' -U postgres
|
11
|
-
- mysql -e 'create database strong_migrations_test;'
|
12
|
-
notifications:
|
13
|
-
email:
|
14
|
-
on_success: never
|
15
|
-
on_failure: change
|
16
|
-
matrix:
|
17
|
-
include:
|
18
|
-
- gemfile: test/gemfiles/mysql2.gemfile
|
19
|
-
env: ADAPTER=mysql2
|
20
|
-
rvm: 2.4.1
|
data/Gemfile
DELETED
data/Rakefile
DELETED
data/strong_migrations.gemspec
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
# coding: utf-8
|
2
|
-
lib = File.expand_path("../lib", __FILE__)
|
3
|
-
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require "strong_migrations/version"
|
5
|
-
|
6
|
-
Gem::Specification.new do |spec|
|
7
|
-
spec.name = "strong_migrations"
|
8
|
-
spec.version = StrongMigrations::VERSION
|
9
|
-
spec.authors = ["Bob Remeika", "David Waller", "Andrew Kane"]
|
10
|
-
spec.email = ["bob.remeika@gmail.com", "andrew@chartkick.com"]
|
11
|
-
|
12
|
-
spec.summary = "Catch unsafe migrations at dev time"
|
13
|
-
spec.homepage = "https://github.com/ankane/strong_migrations"
|
14
|
-
|
15
|
-
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
16
|
-
spec.bindir = "exe"
|
17
|
-
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
18
|
-
spec.require_paths = ["lib"]
|
19
|
-
|
20
|
-
spec.add_dependency "activerecord", ">= 3.2.0"
|
21
|
-
|
22
|
-
spec.add_development_dependency "bundler"
|
23
|
-
spec.add_development_dependency "rake"
|
24
|
-
spec.add_development_dependency "minitest"
|
25
|
-
spec.add_development_dependency "pg", "< 1"
|
26
|
-
end
|