- Fix background data migrations to work with
includes
/eager_load
on relation - Fix problem with running migrations for
activerecord
8.0.0.rc2
- Enhance columns removal check to check indexes
where
andinclude
options - Do not wait before running retried background migrations
- Fix
add_reference_concurrently
when adding non polymorphic references - Fix progress for background migrations with small number of records
- Fix
add_reference_concurrently
when adding polymorphic references
-
Fix an edge case for background schema migrations
If you use background schema migrations, you need to run
bin/rails generate online_migrations:upgrade bin/rails db:migrate
-
Fix retrying running stuck background schema migrations
-
Fix renaming columns for tables with long names
- Fix idempotency for
add_index
/remove_index
for expression indexes
- Fix
add_reference_concurrently
to be idempotent when adding a foreign key - Fix
enqueue_background_data_migration
to be idempotent
- Fix
add_index_in_background
to be idempotent
- Add ability to cancel background migrations
- Fix setting
started_at
/finished_at
for parents of sharded background schema migrations - Improve retrying of failed sharded background migrations
- Fix a bug when retried background data migration can not start
- Do not run multiple background schema migrations on the same table at the same time
- Fix raising in development when using sharding and background index creation/removal was not enqueued
- Fix background migrations
#progress
possibility to fail with zero division error - Add
ensure_background_data_migration_succeeded
andensure_background_schema_migration_succeeded
migration helpers - Raise in development when background index creation/removal was not enqueued
- Suggest two migrations for adding foreign keys
- Reraise errors when running background schema migrations inline
- Improve error message when background schema migration name is already taken
- Fix copying column background migration to work with primary keys added via
initialize_column_type_change
-
Add support for asynchronous creation/removal of indexes
See
docs/background_schema_migrations.md
for the feature description.
- Reraise errors when running background migrations inline
- Add
remove_background_migration
migration helper - Allow adding bigint foreign keys referencing integer primary keys
- Fix
add_reference_concurrently
to check for mismatched key types
- Fix
MigrationRunner
to considerrun_background_migrations_inline
proc
-
Add ability to configure whether background migrations should be run inline
The previous behavior of running inline in development and test environments is preserved, unless overriden.
config.run_background_migrations_inline = -> { Rails.env.local? }
- Fix calculation of batch ranges for background migration created with explicit ranges
-
Add ability to configure the path where generated background migrations will be placed
# It is placed in lib/ by default. config.background_migrations.migrations_path = "app/lib"
-
Reduce number of queries needed to calculate batch ranges for background migrations
-
Fix
finalize_column_type_change
to not recreate already existing indexes on the temporary column -
Remove potentially heavy queries used to get the ranges of a background migration
-
Require passing model name for background migration helpers when using multiple databases
-
Add
statement_timeout
configuration option -
Make
lock_timeout
argument optional forconfig.lock_retrier
This way, a default lock timeout value will be used (configured in
database.yml
or for the database user). -
Fix a bug that can lead to unfinished children of a sharded background migration
- Fix calculation of batch ranges for sharded background migrations
-
Support sharding for background migrations
Now, if a
relation
inside background migration definition is defined on a sharded model, then that background migration would automatically run on all the shards.To get all the new sharding related schema changes, you need to run:
$ bin/rails generate online_migrations:upgrade $ bin/rails db:migrate
-
Change background migration
progress
to return values in range from 0.0 to 100.0Previously, these were values in range from 0.0 to 1.0 and caused confusion
-
Copy exclusion constraints when changing column type
-
Update
revert_finalize_columns_type_change
to not remove indexes, foreign keys etc -
Fix verbose query logging when
ActiveRecord::Base.logger
isnil
-
Add a shortcut for running background migrations
# Before: OnlineMigrations::BackgroundMigrations::Scheduler.run # After OnlineMigrations.run_background_migrations
-
Add support for
:type_cast_function
toinitialize_column_type_change
helper -
Drop support for Ruby < 2.7 and Rails < 6.1
- Add
auto_analyze
configuration option - Add
alphabetize_schema
configuration option - Fix
backfill_column_for_type_change_in_background
for cast expressions - Fix copying indexes with long names when changing column type
- Enhance error messages with the link to the detailed description
- Fix checking which expression indexes to copy when changing column type
- Fix copying expression indexes when changing column type
-
Add ability to use custom raw sql for
backfill_column_for_type_change
'stype_cast_function
backfill_column_for_type_change(:users, :company_id, type_cast_function: Arel.sql("company_id::integer"))
-
Fix version safety with
revert
- Promote check constraint to
NOT NULL
on PostgreSQL >= 12 when changing column type - Fix
safety_assured
withrevert
- Fix
update_columns_in_batches
when multiple columns are passed - Fix reverting adding/removing not null and text limit constraints
- Add check for
change_column_default
- Add check for
add_unique_constraint
(Active Record >= 7.1) - Add check for
add_column
with stored generated columns
- Fix removing columns having expression indexes on them
- Suggest additional steps for safely renaming a column if Active Record
enumerate_columns_in_select_statements
setting is enabled (implemented in Active Record 7+, disabled by default) - Fix
add_reference_concurrently
to correctly check for existence of foreign keys - Fix column quoting in
add_not_null_constraint
- Fix Schema Cache to correctly retrieve metadata from renamed tables
- Add support for renaming multiple columns at once in the same table
- Fix quoting table/column names across the library
- Fix deffered foreign keys support in
add_foreign_key
(Active Record >= 7) - Reset attempts of failing jobs before executing background migration inline
- Ignore internal Active Record migrations compatibility related options when suggesting a safe column type change
- Added check for
add_exclusion_constraint
- Fix preserving old column options (
:comment
and:collation
) when changing column type - Set
NOT NULL
during new column creation when changing column type for PostgreSQL >= 11
- Support ruby 3.2.0
- Fix removing index by name
- Fix multiple databases support for
start_after
andtarget_version
configs - Fix error when
Rails
defined withoutRails.env
- Improve error message for adding column with a NULL default for PostgreSQL < 11
-
Fix sequence resetting in tests that use fixtures
-
Fix
update_column_in_batches
for SQL subquery valuesIt generated inefficient queries before, e.g.:
update_column_in_batches(:users, :comments_count, Arel.sql(<<~SQL)) (select count(*) from comments where comments.user_id = users.id) SQL
Generated SQL queries before:
update users set comments_count = (..count subquery..) where comments_count is null or comments_count != (..count subquery..)
Generated SQL queries now:
update users set comments_count = (..count subquery..)
-
Fix check for
add_column
withdefault: nil
for PostgreSQL < 11 -
Replacing a unique index when other unique index with the prefix of columns exists is safe
- Raise for possible index corruption in all environments (previously, the check was made only in the production environment)
-
Added check for index corruption with PostgreSQL 14.0 to 14.3
-
No need to separately remove indexes when removing a column from the small table
-
Add ability to perform specific action on a relation or individual records using background migrations
Example, assuming you have lots and lots of fraud likes:
class DeleteFraudLikes < ActiveRecord::Migration[7.0] def up perform_action_on_relation_in_background("Like", { fraud: true }, :delete_all) end end
Example, assuming you added a new column to the users and want to populate it:
class User < ApplicationRecord def generate_invite_token self.invite_token = # some complex logic end end perform_action_on_relation_in_background("User", { invite_token: nil }, :generate_invite_token)
You can use
delete_all
/destroy_all
/update_all
for the whole relation or run specific methods on individual records. -
Add ability to delete records associated with a parent object using background migrations
class Link < ActiveRecord::Base has_many :clicks end class Click < ActiveRecord::Base belongs_to :link end class DeleteSomeLinkClicks < ActiveRecord::Migration[7.0] def up some_link = ... delete_associated_records_in_background("Link", some_link.id, :clicks) end end
-
Add ability to delete orphaned records using background migrations
class User < ApplicationRecord has_many :posts end class Post < ApplicationRecord belongs_to :author, class_name: 'User' end class DeleteOrphanedPosts < ActiveRecord::Migration[7.0] def up delete_orphaned_records_in_background("Post", :author) end end
- Fix missing options in suggested command for columns removal
- Fix retrieving raw postgresql connection
-
Lazy load this gem
-
Add ability to reset counter caches using background migrations
class User < ApplicationRecord has_many :projects end class Project < ApplicationRecord belongs_to :user, counter_cache: true end class ResetUsersProjectsCount < ActiveRecord::Migration[7.0] def up reset_counters_in_background("User", :projects) end end
-
Accept
0
asbatch_pause
value for background migrations -
Ignore default scopes in
CopyColumn
andBackfillColumn
background migrations -
Raise an error for unsupported database versions
-
Fix backfilling code in suggestion for changing column's NOT NULL
New safe operations
- Changing between
text
andcitext
when not indexed - Changing a
string
column to acitext
column when not indexed - Changing a
citext
column to astring
column with no length limit - Increasing the
:precision
of aninterval
column - Changing a
cidr
column to aninet
column - Changing an
xml
column to atext
column - Changing an
xml
column to astring
column with no:limit
- Changing a
bit
column to abit_varying
column - Increasing or removing the
:limit
of abit_varying
column
New unsafe operations
- Decreasing
:precision
of adatetime
column - Decreasing
:limit
of atimestamptz
column - Decreasing
:limit
of abit_varying
column - Adding a
:limit
to abit_varying
column
-
Support ActiveRecord 7.0+ versioned schemas
-
Check for addition of single table inheritance column
See Adding a single table inheritance column for details
-
Add a way to log every SQL query to stdout
See Verbose SQL logs for details
-
Ignore new tables when checking for removing table with multiple fkeys
-
Fix backfilling column in add_column_with_default when default is an expression
-
Check removing a table with multiple foreign keys
-
Check for mismatched reference column types
For example, it detects cases like:
class AddUserIdToProjects < ActiveRecord::Migration[7.0] def change add_column :projects, :user_id, :integer end end
where
users.id
is of typebigint
. -
Add support for multiple databases to
start_after
andtarget_version
configuration optionsOnlineMigrations.configure do |config| config.start_after = { primary: 20211112000000, animals: 20220101000000 } config.target_version = { primary: 10, animals: 14.1 } end
-
Do not suggest
ignored_columns
when removing columns for Active Record 4.2 (ignored_columns
was introduced in 5.0) -
Check replacing indexes
For example, you have an index on
projects.creator_id
. But decide, it is better to have a multicolumn index on[creator_id, created_at]
:class AddIndexOnCreationToProjects < ActiveRecord::Migration[7.0] disable_ddl_transaction! def change remove_index :projects, :creator_id, algorithm: :concurrently # (1) add_index :projects, [:creator_id, :created_at], algorithm: :concurrently # (2) end end
If there is no existing indexes covering
creator_id
, removing an old index (1) before replacing it with the new one (2) might result in slow queries while building the new index. A safer approach is to swap removing the old and creation of the new index operations.
- First release