strong_migrations 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|