online_migrations 0.27.0 → 0.28.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7125a034a085c11fff526219d8f2483dfea610b100486766145b7caf85e07700
4
- data.tar.gz: 609636661c23e939a1766a14097fca30bc01b21666cfcb5e207bc20dfde4923c
3
+ metadata.gz: bcbf178b59ac7d856b8b3b44640aa30bd5bb0bc61c334d90925562da1ca23782
4
+ data.tar.gz: 3034174c45f26e4e70a338faa8074bcb4c926160202f6dd85dc43d6ffc5b7101
5
5
  SHA512:
6
- metadata.gz: 22866111b2a0ba3392d930c60548234f72c1f9dd27309a5b0c5ebff0b06232e5a59d2a6353db51d4c760abdafd90091a8ddf873808fb6cb53bbb755ebc7daf80
7
- data.tar.gz: 16643b7af80d9d20e482a5be141e0ecd4733503ff9a80effcd03516af60270227c1c7d604b4b342c70a553e6fe729b83b9b8eb609f87cf9f5c6bde7e3177eb36
6
+ metadata.gz: 228cbf5deacedaf2017b86a7c6f005c89d454be0fdfe05358d1c33414fa1349cac46fa602901bdb9cf16f2b9bc8f73b6f7e8a935ff754a623182083032d649a4
7
+ data.tar.gz: 3b05af5c90a084eb64ef0f711e0d9ecb88a0e28d73ae3aa3720bbea525454a63061525aa56c56d251fc8044c6741f9cc94258f6eaf2b1cbd4325c01be86390e7
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  ## master (unreleased)
2
2
 
3
+ ## 0.28.0 (2025-06-26)
4
+
5
+ - Support renaming columns and tables for tables within custom schemas
6
+ - Include operation name into the background schema migrations names
7
+
8
+ ## 0.27.1 (2025-05-08)
9
+
10
+ - Fix background data migrations to enumerate using the correct shard
11
+
3
12
  ## 0.27.0 (2025-05-01)
4
13
 
5
14
  - **WARNING**: This release has breaking changes! See `docs/0.27-upgrade.md` for release notes
data/docs/0.27-upgrade.md CHANGED
@@ -9,7 +9,7 @@ To upgrade:
9
9
  * Upgrade gem to v0.27: `gem 'online_migrations', '~> 0.27.0'`
10
10
  * Upgrade the gem's initializer in `config/online_migrations.rb` by referring to the [newest contents](https://github.com/fatkodima/online_migrations/blob/master/lib/generators/online_migrations/templates/initializer.rb.tt)
11
11
 
12
- If you don't use any of the [background data migrations](docs/background_data_migrations.md) or [background schema migrations](docs/background_schema_migrations.md), then this is probably all you need.
12
+ If you don't use any of the [background data migrations](background_data_migrations.md) or [background schema migrations](background_schema_migrations.md), then this is probably all you need.
13
13
 
14
14
  If you use background data migrations:
15
15
 
@@ -21,4 +21,4 @@ If you use background data migrations:
21
21
  $ bin/rails db:migrate
22
22
  ```
23
23
 
24
- Look at [background data migrations guide](docs/background_data_migrations.md) to find the API changes and new features.
24
+ Look at [background data migrations guide](background_data_migrations.md) to find the API changes and new features.
@@ -110,6 +110,9 @@ OnlineMigrations.configure do |config|
110
110
  # The number of seconds that must pass before the cancelling or pausing data migration is considered stuck.
111
111
  config.background_data_migrations.stuck_timeout = 5.minutes
112
112
 
113
+ # The pause interval between each data migration's `process` method execution (in seconds).
114
+ config.background_data_migrations.iteration_pause = Rails.env.production? ? 0.02 : 0
115
+
113
116
  # The callback to perform when an error occurs during the data migration.
114
117
  # config.background_data_migrations.error_handler = ->(error, errored_migration) do
115
118
  # Bugsnag.notify(error) do |notification|
@@ -45,10 +45,6 @@ module OnlineMigrations
45
45
  @migration.start
46
46
  end
47
47
 
48
- def around_iteration(&block)
49
- @migration.on_shard_if_present(&block)
50
- end
51
-
52
48
  def on_resume
53
49
  @data_migration.after_resume
54
50
  end
@@ -140,6 +136,12 @@ module OnlineMigrations
140
136
  end
141
137
 
142
138
  private
139
+ # It would be better for sidekiq to have a callback like `around_perform`,
140
+ # but currently this is the way to make job iteration shard aware.
141
+ def iterate_with_enumerator(enumerator, arguments)
142
+ @migration.on_shard_if_present { super }
143
+ end
144
+
143
145
  THROTTLE_CHECK_INTERVAL = 5 # seconds
144
146
  private_constant :THROTTLE_CHECK_INTERVAL
145
147
 
@@ -28,7 +28,7 @@ module OnlineMigrations
28
28
  schema_creation = ActiveRecord::ConnectionAdapters::PostgreSQL::SchemaCreation.new(self)
29
29
  definition = schema_creation.accept(create_index)
30
30
 
31
- enqueue_background_schema_migration(index.name, table_name, definition: definition, **migration_options)
31
+ enqueue_background_schema_migration("Add index #{index.name}", table_name, definition: definition, **migration_options)
32
32
  end
33
33
 
34
34
  def remove_index_in_background(table_name, column_name = nil, name:, **options)
@@ -42,7 +42,7 @@ module OnlineMigrations
42
42
  end
43
43
 
44
44
  definition = "DROP INDEX CONCURRENTLY IF EXISTS #{quote_column_name(name)}"
45
- enqueue_background_schema_migration(name, table_name, definition: definition, **migration_options)
45
+ enqueue_background_schema_migration("Remove index #{name}", table_name, definition: definition, **migration_options)
46
46
  end
47
47
 
48
48
  def validate_foreign_key_in_background(from_table, to_table = nil, **options)
@@ -62,7 +62,7 @@ module OnlineMigrations
62
62
  ALTER TABLE #{quote_table_name(table_name)}
63
63
  VALIDATE CONSTRAINT #{quote_table_name(constraint_name)}
64
64
  SQL
65
- enqueue_background_schema_migration(constraint_name, table_name, definition: definition, **options)
65
+ enqueue_background_schema_migration("Validate #{constraint_name}", table_name, definition: definition, **options)
66
66
  end
67
67
 
68
68
  # Ensures that the background schema migration with the provided migration name succeeded.
@@ -78,7 +78,7 @@ module OnlineMigrations
78
78
  # ensure_background_schema_migration_succeeded("index_users_on_email")
79
79
  #
80
80
  def ensure_background_schema_migration_succeeded(migration_name)
81
- migrations = Migration.where(migration_name: migration_name).to_a
81
+ migrations = Migration.where("migration_name ILIKE ?", "%#{migration_name}%").to_a
82
82
 
83
83
  if migrations.empty?
84
84
  Utils.raise_in_prod_or_say_in_dev("Could not find background schema migration(s): '#{migration_name}'.")
@@ -97,12 +97,13 @@ module OnlineMigrations
97
97
  if connection_class_name
98
98
  klass = connection_class_name.constantize
99
99
  connection_class = Utils.find_connection_class(klass)
100
- # Normalize to the real connection class name.
101
- connection_class_name = connection_class.name
102
100
  else
103
101
  connection_class = ActiveRecord::Base
104
102
  end
105
103
 
104
+ # Normalize to the real connection class name.
105
+ connection_class_name = connection_class.name
106
+
106
107
  shards = Utils.shard_names(connection_class)
107
108
  shards = [nil] if shards.size == 1
108
109
 
@@ -152,7 +152,11 @@ module OnlineMigrations
152
152
  # revert_initialize_column_type_change(:files, :size)
153
153
  #
154
154
  def revert_initialize_column_type_change(table_name, column_name, _new_type = nil, **_options)
155
- cleanup_column_type_change(table_name, column_name)
155
+ tmp_column_name = __change_type_column(column_name)
156
+ transaction do
157
+ __remove_copy_triggers(table_name, column_name, tmp_column_name)
158
+ remove_column(table_name, tmp_column_name)
159
+ end
156
160
  end
157
161
 
158
162
  # Same as `revert_initialize_column_type_change` but for multiple columns.
@@ -160,7 +164,12 @@ module OnlineMigrations
160
164
  #
161
165
  def revert_initialize_columns_type_change(table_name, columns_and_types, **_options)
162
166
  column_names = columns_and_types.map(&:first)
163
- cleanup_columns_type_change(table_name, *column_names)
167
+ tmp_column_names = column_names.map { |column_name| __change_type_column(column_name) }
168
+
169
+ transaction do
170
+ __remove_copy_triggers(table_name, column_names, tmp_column_names)
171
+ remove_columns(table_name, *tmp_column_names)
172
+ end
164
173
  end
165
174
 
166
175
  # Backfills data from the old column to the new column.
@@ -347,6 +356,7 @@ module OnlineMigrations
347
356
  # the original column type to be able to revert.
348
357
  #
349
358
  def cleanup_column_type_change(table_name, column_name)
359
+ __ensure_not_in_transaction!
350
360
  cleanup_columns_type_change(table_name, column_name)
351
361
  end
352
362
 
@@ -354,6 +364,8 @@ module OnlineMigrations
354
364
  # @see #cleanup_column_type_change
355
365
  #
356
366
  def cleanup_columns_type_change(table_name, *column_names)
367
+ __ensure_not_in_transaction!
368
+
357
369
  tmp_column_names = column_names.map { |column_name| __change_type_column(column_name) }
358
370
 
359
371
  # Safely remove existing indexes and foreign keys first, if any.
@@ -230,6 +230,8 @@ during writes works automatically). For most column type changes, this does not
230
230
  7. Finally, if everything works as expected, remove copy trigger and old column:
231
231
 
232
232
  class Cleanup<%= migration_name %> < <%= migration_parent %>
233
+ disable_ddl_transaction!
234
+
233
235
  def up
234
236
  <%= cleanup_code %>
235
237
  end
@@ -52,15 +52,14 @@ module OnlineMigrations
52
52
  private
53
53
  def renamed_table?(connection, table_name)
54
54
  table_renames = OnlineMigrations.config.table_renames
55
- if table_renames.key?(table_name)
56
- views = connection.views
57
- table_renames[table_name] if views.include?(table_name)
55
+ if table_renames.key?(table_name) && connection.view_exists?(table_name)
56
+ table_renames[table_name]
58
57
  end
59
58
  end
60
59
 
61
60
  def renamed_column?(connection, table_name)
62
61
  column_renames = OnlineMigrations.config.column_renames
63
- column_renames.key?(table_name) && connection.views.include?(table_name)
62
+ column_renames.key?(table_name) && connection.view_exists?(table_name)
64
63
  end
65
64
 
66
65
  def column_rename_table(table_name)
@@ -131,14 +130,21 @@ module OnlineMigrations
131
130
  def renamed_table?(pool, table_name)
132
131
  table_renames = OnlineMigrations.config.table_renames
133
132
  if table_renames.key?(table_name)
134
- views = pool.with_connection(&:views)
135
- table_renames[table_name] if views.include?(table_name)
133
+ view_exists = pool.with_connection do |connection|
134
+ connection.view_exists?(table_name)
135
+ end
136
+
137
+ table_renames[table_name] if view_exists
136
138
  end
137
139
  end
138
140
 
139
141
  def renamed_column?(pool, table_name)
140
142
  column_renames = OnlineMigrations.config.column_renames
141
- column_renames.key?(table_name) && pool.with_connection(&:views).include?(table_name)
143
+ return false if !column_renames.key?(table_name)
144
+
145
+ pool.with_connection do |connection|
146
+ connection.view_exists?(table_name)
147
+ end
142
148
  end
143
149
 
144
150
  def column_rename_table(table_name)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OnlineMigrations
4
- VERSION = "0.27.0"
4
+ VERSION = "0.28.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: online_migrations
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.27.0
4
+ version: 0.28.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - fatkodima
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-05-01 00:00:00.000000000 Z
11
+ date: 2025-06-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord