README.md in strong_migrations-0.1.0 vs README.md in strong_migrations-0.1.1
- old
+ new
@@ -12,38 +12,25 @@
gem 'strong_migrations'
```
## Dangerous Operations
-- adding an index non-concurrently
-- adding a column with a non-null default value
+- adding a column with a non-null default value to an existing table
- changing the type of a column
- renaming a table
- renaming a column
- removing a column
-- adding a `json` column (Postgres only)
+- adding an index non-concurrently (Postgres only)
+- adding a `json` column to an existing table (Postgres only)
For more info, check out:
- [Rails Migrations with No Downtime](http://pedro.herokuapp.com/past/2011/7/13/rails_migrations_with_no_downtime/)
- [Safe Operations For High Volume PostgreSQL](https://www.braintreepayments.com/blog/safe-operations-for-high-volume-postgresql/) (if it’s relevant)
## The Zero Downtime Way
-### Adding an index
-
-Add indexes concurrently.
-
-```ruby
-class AddSomeIndexToUsers < ActiveRecord::Migration
- def change
- commit_db_transaction
- add_index :users, :some_index, algorithm: :concurrently
- end
-end
-```
-
### Adding a column with a default value
1. Add the column without a default value
2. Commit the transaction
3. Backfill the column
@@ -73,12 +60,10 @@
end
```
### Renaming or changing the type of a column
-There’s no way to do this without downtime.
-
If you really have to:
1. Create a new column
2. Write to both columns
3. Backfill data from the old column to the new column
@@ -86,15 +71,22 @@
5. Stop writing to the old column
6. Drop the old column
### Renaming a table
-Same as renaming a column - see above.
+If you really have to:
+1. Create a new table
+2. Write to both tables
+3. Backfill data from the old table to new table
+4. Move reads from the old table to the new table
+5. Stop writing to the old table
+6. Drop the old table
+
### Removing a column
-Tell ActiveRecord to [ignore the column](http://pedro.herokuapp.com/past/2011/7/13/rails_migrations_with_no_downtime/) from its cache.
+Tell ActiveRecord to ignore the column from its cache.
```ruby
class User
def self.columns
super.reject { |c| c.name == "some_column" }
@@ -102,12 +94,25 @@
end
```
Once it’s deployed, create a migration to remove the column.
-### Adding a json column
+### Adding an index (Postgres)
-There’s no equality operator for the `json` column type. Replace all calls to `uniq` with a custom scope.
+Add indexes concurrently.
+
+```ruby
+class AddSomeIndexToUsers < ActiveRecord::Migration
+ def change
+ commit_db_transaction
+ add_index :users, :some_index, algorithm: :concurrently
+ end
+end
+```
+
+### Adding a json column (Postgres)
+
+There’s no equality operator for the `json` column type, which causes issues for `SELECT DISTINCT` queries. Replace all calls to `uniq` with a custom scope.
```ruby
scope :uniq_on_id, -> { select("DISTINCT ON (your_table.id) your_table.*") }
```