online_migrations 0.32.0 → 0.33.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: 52861ed084d1bd3fd77bc08ea3f1b6aae8c26b58f1fc5ef08f181c18feb8d390
4
- data.tar.gz: 92b111ad1679c421cbe97e206b18b2e3126cfb2c2fe4247de70e793a49ac112a
3
+ metadata.gz: 7f092b18d7bc864ba2232a41727e136bb86469279bdc3ad4c04a49a49628fb95
4
+ data.tar.gz: b7349d9b1c818ed4fefd078f7262bb380bb22a34109be13d2ead3191f338dbc9
5
5
  SHA512:
6
- metadata.gz: 0eeeae19aec88ff880a076e3f82c60a99fb210b62ac3aeb881fb601ea14d34de8139ad9b42f839ffc29a83ffa65f6e787f36d9940ec06d2602982e562cda6e13
7
- data.tar.gz: 82d54ab9eff606c039e96f8f158c4991ffd861456237fcfcef9578e63cc212e8db3a9abc1be0ec92d40e51e2ac37c8748e2396db560a7737d680bb01357b4519
6
+ metadata.gz: 4a52e29b327dbecae7f1c31fa4020fa5b428c5f830ea34215695bfd827c787c90146dda6dd12045a5c7f4cc2136741bb1a08b76b2a3ad7273f69c028d192a764
7
+ data.tar.gz: 6175ee34939fbdc6c21605320c36cfdeca971458381e1d6e465e7b464b302914f87f69c7bbcfc50c3b150fc9b9d6d8d34e0d0a1fd2a0573940aa1efa36e983a5
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  ## master (unreleased)
2
2
 
3
+ ## 0.33.0 (2026-02-04)
4
+
5
+ - Change background migrations default status to "pending"
6
+
7
+ Note: Run `bin/rails generate online_migrations:upgrade` if using background migrations.
8
+
9
+ - Fix copying partial indexes when changing column type
10
+
3
11
  ## 0.32.0 (2026-01-07)
4
12
 
5
13
  - Add ability to create delayed background migrations
@@ -300,7 +300,8 @@ end
300
300
 
301
301
  Data Migrations can be in various states during its execution:
302
302
 
303
- * **enqueued**: A migration has been enqueued by the user.
303
+ * **pending**: A migration has been created by the user.
304
+ * **enqueued**: A migration has been enqueued by the scheduler.
304
305
  * **running**: A migration is being performed by a migration executor.
305
306
  * **pausing**: A migration has been told to pause but is finishing work.
306
307
  * **paused**: A migration was paused in the middle of the run by the user.
@@ -312,7 +313,8 @@ Data Migrations can be in various states during its execution:
312
313
  migration.pause
313
314
  ```
314
315
 
315
- * **failed**: A migration raises an exception when running.
316
+ * **errored**: A migration raised an error during last run.
317
+ * **failed**: A migration raises an error when running and retry attempts exceeded.
316
318
  * **succeeded**: A migration finished without error.
317
319
  * **cancelling**: A migration has been told to cancel but is finishing work.
318
320
  * **cancelled**: A migration was cancelled by the user.
@@ -132,7 +132,7 @@ Available events:
132
132
 
133
133
  Background Schema Migrations can be in various states during its execution:
134
134
 
135
- * **enqueued**: A migration has been enqueued by the user.
135
+ * **pending**: A migration has been created by the user.
136
136
  * **running**: A migration is being performed by a migration executor.
137
137
  * **errored**: A migration raised an error during last run.
138
138
  * **failed**: A migration raises an error when running and retry attempts exceeded.
@@ -0,0 +1,8 @@
1
+ class BackgroundDataMigrationsChangeStatusDefault < <%= migration_parent %>
2
+ def change
3
+ safety_assured do
4
+ change_column_default :background_data_migrations, :status, from: "enqueued", to: "pending"
5
+ change_column_default :background_schema_migrations, :status, from: "enqueued", to: "pending"
6
+ end
7
+ end
8
+ end
@@ -3,7 +3,7 @@ class InstallOnlineMigrations < <%= migration_parent %>
3
3
  create_table :background_data_migrations do |t|
4
4
  t.string :migration_name, null: false
5
5
  t.jsonb :arguments, default: [], null: false
6
- t.string :status, default: "enqueued", null: false
6
+ t.string :status, default: "pending", null: false
7
7
  t.string :shard
8
8
  t.string :cursor
9
9
  t.string :jid
@@ -28,7 +28,7 @@ class InstallOnlineMigrations < <%= migration_parent %>
28
28
  t.string :migration_name, null: false
29
29
  t.string :table_name, null: false
30
30
  t.string :definition, null: false
31
- t.string :status, default: "enqueued", null: false
31
+ t.string :status, default: "pending", null: false
32
32
  t.string :shard
33
33
  t.integer :statement_timeout
34
34
  t.datetime :started_at
@@ -52,6 +52,11 @@ module OnlineMigrations
52
52
  migrations << "background_data_migrations_remove_iteration_pause_default"
53
53
  end
54
54
 
55
+ status_column = connection.columns(:background_data_migrations).find { |c| c.name == "status" }
56
+ if status_column.default == "enqueued"
57
+ migrations << "background_migrations_change_status_default"
58
+ end
59
+
55
60
  migrations
56
61
  end
57
62
 
@@ -11,11 +11,13 @@ module OnlineMigrations
11
11
  include ShardAware
12
12
 
13
13
  STATUSES = [
14
- "enqueued", # The migration has been enqueued by the user.
14
+ "pending", # The migration has been created by the user.
15
+ "enqueued", # The migration has been enqueued by the scheduler.
15
16
  "running", # The migration is being performed by a migration executor.
16
17
  "pausing", # The migration has been told to pause but is finishing work.
17
18
  "paused", # The migration was paused in the middle of the run by the user.
18
- "failed", # The migration raises an exception when running.
19
+ "errored", # The migration raised an error during last run.
20
+ "failed", # The migration raises an error when running and retry attempts exceeded.
19
21
  "succeeded", # The migration finished without error.
20
22
  "cancelling", # The migration has been told to cancel but is finishing work.
21
23
  "cancelled", # The migration was cancelled by the user.
@@ -25,8 +27,10 @@ module OnlineMigrations
25
27
  COMPLETED_STATUSES = ["succeeded", "failed", "cancelled"]
26
28
 
27
29
  ACTIVE_STATUSES = [
30
+ "pending",
28
31
  "enqueued",
29
32
  "running",
33
+ "failed",
30
34
  "pausing",
31
35
  "paused",
32
36
  "cancelling",
@@ -87,7 +91,7 @@ module OnlineMigrations
87
91
  end
88
92
 
89
93
  # Returns whether the migration is active, which is defined as
90
- # having a status of enqueued, running, pausing, paused, or cancelling.
94
+ # having a status of pending, enqueued, running, pausing, paused, or cancelling.
91
95
  #
92
96
  # @return [Boolean] whether the migration is active.
93
97
  #
@@ -107,22 +111,18 @@ module OnlineMigrations
107
111
  end
108
112
 
109
113
  # Returns whether a migration is stuck, which is defined as having a status of
110
- # cancelling or pausing, and not having been updated in the last 5 minutes.
114
+ # running, cancelling or pausing, and not having been updated in the last 5 minutes.
111
115
  #
112
116
  # @return [Boolean] whether the migration is stuck.
113
117
  #
114
118
  def stuck?
115
119
  stuck_timeout = OnlineMigrations.config.background_data_migrations.stuck_timeout
116
- (cancelling? || pausing?) && updated_at <= stuck_timeout.ago
120
+ (running? || cancelling? || pausing?) && updated_at <= stuck_timeout.ago
117
121
  end
118
122
 
119
123
  # @private
120
124
  def start
121
- if running? && !started?
122
- update!(started_at: Time.current)
123
- data_migration.after_start
124
- true
125
- elsif enqueued?
125
+ if enqueued?
126
126
  update!(status: :running, started_at: Time.current)
127
127
  data_migration.after_start
128
128
  true
@@ -137,7 +137,7 @@ module OnlineMigrations
137
137
  #
138
138
  def enqueue
139
139
  if delayed?
140
- enqueued!
140
+ pending!
141
141
  true
142
142
  else
143
143
  false
@@ -153,7 +153,7 @@ module OnlineMigrations
153
153
 
154
154
  if paused? || delayed? || stuck?
155
155
  update!(status: :cancelled, finished_at: Time.current)
156
- elsif enqueued?
156
+ elsif pending? || enqueued? || errored?
157
157
  cancelled!
158
158
  else
159
159
  cancelling!
@@ -169,7 +169,7 @@ module OnlineMigrations
169
169
  def pause
170
170
  return false if completed?
171
171
 
172
- if enqueued? || delayed? || stuck?
172
+ if pending? || enqueued? || delayed? || stuck? || errored?
173
173
  paused!
174
174
  else
175
175
  pausing!
@@ -184,7 +184,7 @@ module OnlineMigrations
184
184
  #
185
185
  def resume
186
186
  if paused?
187
- enqueued!
187
+ pending!
188
188
  true
189
189
  else
190
190
  false
@@ -235,13 +235,14 @@ module OnlineMigrations
235
235
  end
236
236
 
237
237
  # @private
238
- def persist_error(error)
238
+ def persist_error(error, attempt)
239
239
  backtrace = error.backtrace
240
240
  backtrace_cleaner = OnlineMigrations.config.backtrace_cleaner
241
241
  backtrace = backtrace_cleaner.clean(backtrace) if backtrace_cleaner
242
+ status = attempt >= max_attempts ? :failed : :errored
242
243
 
243
244
  update!(
244
- status: :failed,
245
+ status: status,
245
246
  finished_at: Time.current,
246
247
  error_class: error.class.name,
247
248
  error_message: error.message,
@@ -290,7 +291,7 @@ module OnlineMigrations
290
291
  def retry
291
292
  if failed?
292
293
  update!(
293
- status: :enqueued,
294
+ status: :pending,
294
295
  started_at: nil,
295
296
  finished_at: nil,
296
297
  error_class: nil,
@@ -382,7 +382,7 @@ module OnlineMigrations
382
382
  connection_class = options[:connection_class_name].constantize
383
383
  shards = Utils.shard_names(connection_class)
384
384
  shards = [nil] if shards.size == 1
385
- status = delay ? :delayed : :enqueued
385
+ status = delay ? :delayed : :pending
386
386
 
387
387
  shards.each do |shard|
388
388
  # Can't use `find_or_create_by` or hash syntax here, because it does not correctly work with json `arguments`.
@@ -8,23 +8,17 @@ module OnlineMigrations
8
8
 
9
9
  sidekiq_options backtrace: true
10
10
 
11
- sidekiq_retry_in do |count, _exception, jobhash|
11
+ sidekiq_retry_in do |count, exception, jobhash|
12
12
  migration_id = jobhash["args"].fetch(0)
13
13
  migration = Migration.find(migration_id)
14
+ migration.persist_error(exception, count + 1)
15
+ OnlineMigrations.config.background_data_migrations.error_handler.call(exception, migration)
14
16
 
15
17
  if count + 1 >= migration.max_attempts
16
18
  :kill
17
19
  end
18
20
  end
19
21
 
20
- sidekiq_retries_exhausted do |jobhash, exception|
21
- migration_id = jobhash["args"].fetch(0)
22
- migration = Migration.find(migration_id)
23
- migration.persist_error(exception)
24
-
25
- OnlineMigrations.config.background_data_migrations.error_handler.call(exception, migration)
26
- end
27
-
28
22
  TICKER_INTERVAL = 5 # seconds
29
23
 
30
24
  def initialize
@@ -57,6 +51,15 @@ module OnlineMigrations
57
51
  end
58
52
 
59
53
  def on_resume
54
+ if @migration.errored? # the job was retried
55
+ @migration.update!(
56
+ status: :running,
57
+ error_class: nil,
58
+ error_message: nil,
59
+ backtrace: nil
60
+ )
61
+ end
62
+
60
63
  @data_migration.after_resume
61
64
  end
62
65
 
@@ -126,7 +129,7 @@ module OnlineMigrations
126
129
  end
127
130
 
128
131
  def each_iteration(item, _migration_id)
129
- if @migration.cancelling? || @migration.pausing? || @migration.paused?
132
+ if @migration.cancelling? || @migration.cancelled? || @migration.pausing? || @migration.paused?
130
133
  # Finish this exact sidekiq job. When the migration is paused
131
134
  # and will be resumed, a new job will be enqueued.
132
135
  finished = true
@@ -6,6 +6,7 @@ module OnlineMigrations
6
6
  class MigrationStatusValidator < ActiveModel::Validator
7
7
  # Valid status transitions a Migration can make.
8
8
  VALID_STATUS_TRANSITIONS = {
9
+ "pending" => ["enqueued", "paused", "cancelled"],
9
10
  # enqueued -> running occurs when the migration starts performing.
10
11
  # enqueued -> paused occurs when the migration is paused before starting.
11
12
  # enqueued -> cancelled occurs when the migration is cancelled before starting.
@@ -15,11 +16,13 @@ module OnlineMigrations
15
16
  # running -> succeeded occurs when the migration completes successfully.
16
17
  # running -> pausing occurs when a user pauses the migration as it's performing.
17
18
  # running -> cancelling occurs when a user cancels the migration as it's performing.
18
- # running -> failed occurs when the job raises an exception when running.
19
+ # running -> errored occurs when the migration raised an error during the last run.
20
+ # running -> failed occurs when the migration raises an error when running and retry attempts exceeded.
19
21
  "running" => [
20
22
  "succeeded",
21
23
  "pausing",
22
24
  "cancelling",
25
+ "errored",
23
26
  "failed",
24
27
  ],
25
28
  # pausing -> paused occurs when the migration actually halts performing and
@@ -32,22 +35,23 @@ module OnlineMigrations
32
35
  # nothing in its collection to process.
33
36
  # pausing -> failed occurs when the job raises an exception after the
34
37
  # user has paused it.
35
- "pausing" => ["paused", "cancelling", "succeeded", "failed"],
36
- # paused -> enqueued occurs when the migration is resumed after being paused.
38
+ "pausing" => ["paused", "cancelling", "succeeded", "errored", "failed"],
39
+ # paused -> pending occurs when the migration is resumed after being paused.
37
40
  # paused -> cancelled when the user cancels the migration after it is paused.
38
- "paused" => ["enqueued", "cancelled"],
39
- # failed -> enqueued occurs when the migration is retried after encounting an error.
40
- "failed" => ["enqueued"],
41
+ "paused" => ["pending", "cancelled"],
42
+ "errored" => ["running", "failed", "cancelled", "paused"],
43
+ # failed -> pending occurs when the migration is retried after encounting an error.
44
+ "failed" => ["pending"],
41
45
  # cancelling -> cancelled occurs when the migration actually halts performing
42
46
  # and occupies a status of cancelled.
43
47
  # cancelling -> succeeded occurs when the migration completes immediately after
44
48
  # being cancelled. See description for pausing -> succeeded.
45
49
  # cancelling -> failed occurs when the job raises an exception after the
46
50
  # user has cancelled it.
47
- "cancelling" => ["cancelled", "succeeded", "failed"],
48
- # delayed -> enqueued occurs when the delayed migration was approved by the user to start running.
51
+ "cancelling" => ["cancelled", "succeeded", "errored", "failed"],
52
+ # delayed -> pending occurs when the delayed migration was approved by the user to start running.
49
53
  # delayed -> cancelled occurs when the delayed migration was cancelled.
50
- "delayed" => ["enqueued", "cancelled"],
54
+ "delayed" => ["pending", "cancelled"],
51
55
  }
52
56
 
53
57
  def validate(record)
@@ -34,13 +34,13 @@ module OnlineMigrations
34
34
  relation = relation.where(shard: shard) if shard
35
35
 
36
36
  with_lock do
37
- running = relation.running
38
- enqueued = relation.enqueued
37
+ stuck_migrations, active_migrations = relation.running.partition(&:stuck?)
38
+ runnable_migrations = relation.pending + stuck_migrations
39
39
 
40
40
  # Ensure no more than 'concurrency' migrations are running at the same time.
41
- remaining_to_enqueue = concurrency - running.count
41
+ remaining_to_enqueue = concurrency - active_migrations.count
42
42
  if remaining_to_enqueue > 0
43
- migrations_to_enqueue = enqueued.limit(remaining_to_enqueue)
43
+ migrations_to_enqueue = runnable_migrations.take(remaining_to_enqueue)
44
44
  migrations_to_enqueue.each do |migration|
45
45
  enqueue_migration(migration)
46
46
  end
@@ -67,10 +67,11 @@ module OnlineMigrations
67
67
  def enqueue_migration(migration)
68
68
  job = OnlineMigrations.config.background_data_migrations.job
69
69
  job_class = job.constantize
70
+ migration.update!(status: :enqueued)
70
71
 
71
72
  jid = job_class.perform_async(migration.id)
72
73
  if jid
73
- migration.update!(status: :running, jid: jid)
74
+ migration.update!(jid: jid)
74
75
  end
75
76
  end
76
77
  end
@@ -11,7 +11,7 @@ module OnlineMigrations
11
11
  include ShardAware
12
12
 
13
13
  STATUSES = [
14
- "enqueued", # The migration has been enqueued by the user.
14
+ "pending", # The migration has been created by the user.
15
15
  "running", # The migration is being performed by a migration executor.
16
16
  "errored", # The migration raised an error during last run.
17
17
  "failed", # The migration raises an error when running and retry attempts exceeded.
@@ -25,7 +25,7 @@ module OnlineMigrations
25
25
  self.table_name = :background_schema_migrations
26
26
 
27
27
  scope :queue_order, -> { order(created_at: :asc) }
28
- scope :active, -> { where(status: [:enqueued, :running, :errored]) }
28
+ scope :active, -> { where(status: [:pending, :running, :errored]) }
29
29
 
30
30
  alias_attribute :name, :migration_name
31
31
 
@@ -59,12 +59,12 @@ module OnlineMigrations
59
59
  end
60
60
 
61
61
  # Returns whether the migration is active, which is defined as
62
- # having a status of enqueued, or running.
62
+ # having a status of pending, or running.
63
63
  #
64
64
  # @return [Boolean] whether the migration is active.
65
65
  #
66
66
  def active?
67
- enqueued? || running?
67
+ pending? || running?
68
68
  end
69
69
 
70
70
  # Returns whether this migration is pausable.
@@ -98,7 +98,7 @@ module OnlineMigrations
98
98
  def retry
99
99
  if failed?
100
100
  update!(
101
- status: :enqueued,
101
+ status: :pending,
102
102
  attempts: 0,
103
103
  started_at: nil,
104
104
  finished_at: nil,
@@ -119,7 +119,7 @@ module OnlineMigrations
119
119
  #
120
120
  def enqueue
121
121
  if delayed?
122
- enqueued!
122
+ pending!
123
123
  true
124
124
  else
125
125
  false
@@ -133,7 +133,7 @@ module OnlineMigrations
133
133
  def cancel
134
134
  if completed?
135
135
  false
136
- elsif enqueued? || errored? || delayed? || stuck?
136
+ elsif pending? || errored? || delayed? || stuck?
137
137
  cancelled!
138
138
  true
139
139
  end
@@ -107,7 +107,7 @@ module OnlineMigrations
107
107
  shards = Utils.shard_names(connection_class)
108
108
  shards = [nil] if shards.size == 1
109
109
 
110
- status = delay ? :delayed : :enqueued
110
+ status = delay ? :delayed : :pending
111
111
 
112
112
  shards.each do |shard|
113
113
  migration = Migration.create_with(**options, status: status)
@@ -115,7 +115,7 @@ module OnlineMigrations
115
115
 
116
116
  if Utils.run_background_migrations_inline?
117
117
  # Run migration again in development.
118
- migration.update_column(:status, :enqueued) if !migration.enqueued?
118
+ migration.update_column(:status, :pending) if !migration.pending?
119
119
 
120
120
  runner = MigrationRunner.new(migration)
121
121
  runner.run
@@ -13,7 +13,7 @@ module OnlineMigrations
13
13
  def run
14
14
  return if migration.cancelled? || migration.succeeded?
15
15
 
16
- migration.running! if migration.enqueued? || migration.errored?
16
+ migration.running! if migration.pending? || migration.errored?
17
17
  migration_payload = { migration: migration }
18
18
 
19
19
  if migration.attempts == 0
@@ -5,8 +5,8 @@ module OnlineMigrations
5
5
  # @private
6
6
  class MigrationStatusValidator < ActiveModel::Validator
7
7
  VALID_STATUS_TRANSITIONS = {
8
- # enqueued -> running occurs when the migration starts performing.
9
- "enqueued" => ["running", "cancelled"],
8
+ # pending -> running occurs when the migration starts performing.
9
+ "pending" => ["running", "cancelled"],
10
10
  # running -> succeeded occurs when the migration completes successfully.
11
11
  # running -> errored occurs when the migration raised an error during the last run.
12
12
  # running -> failed occurs when the migration raises an error when running and retry attempts exceeded.
@@ -14,12 +14,12 @@ module OnlineMigrations
14
14
  # errored -> running occurs when previously errored migration starts running
15
15
  # errored -> failed occurs when the migration raises an error when running and retry attempts exceeded.
16
16
  "errored" => ["running", "failed", "cancelled"],
17
- # failed -> enqueued occurs when the failed migration is enqueued to be retried.
17
+ # failed -> pending occurs when the failed migration is enqueued to be retried.
18
18
  # failed -> running occurs when the failed migration is retried.
19
- "failed" => ["enqueued", "running", "cancelled"],
20
- # delayed -> enqueued occurs when the delayed migration was approved by the user to start running.
19
+ "failed" => ["pending", "running", "cancelled"],
20
+ # delayed -> pending occurs when the delayed migration was approved by the user to start running.
21
21
  # delayed -> cancelled occurs when the delayed migration was cancelled.
22
- "delayed" => ["enqueued", "cancelled"],
22
+ "delayed" => ["pending", "cancelled"],
23
23
  }
24
24
 
25
25
  def validate(record)
@@ -36,7 +36,7 @@ module OnlineMigrations
36
36
  private
37
37
  def find_migration(**options)
38
38
  stuck_migrations, active_migrations = Migration.running.partition(&:stuck?)
39
- runnable_migrations = (Migration.enqueued + Migration.errored + stuck_migrations).sort_by(&:created_at)
39
+ runnable_migrations = (Migration.pending + Migration.errored + stuck_migrations).sort_by(&:created_at)
40
40
 
41
41
  if options.key?(:shard)
42
42
  runnable_migrations = runnable_migrations.select { |migration| migration.shard.to_s == options[:shard].to_s }
@@ -436,7 +436,10 @@ module OnlineMigrations
436
436
  }
437
437
 
438
438
  options[:using] = index.using if index.using
439
- options[:where] = index.where if index.where
439
+
440
+ if index.where
441
+ options[:where] = index.where.gsub(/\b#{from_column}\b/, to_column)
442
+ end
440
443
 
441
444
  if index.opclasses.present?
442
445
  opclasses = index.opclasses.dup
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OnlineMigrations
4
- VERSION = "0.32.0"
4
+ VERSION = "0.33.0"
5
5
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: online_migrations
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.32.0
4
+ version: 0.33.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - fatkodima
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-01-07 00:00:00.000000000 Z
10
+ date: 2026-02-04 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: activerecord
@@ -42,6 +42,7 @@ files:
42
42
  - lib/generators/online_migrations/templates/add_timestamps_to_background_migrations.rb.tt
43
43
  - lib/generators/online_migrations/templates/background_data_migrations_add_iteration_pause.rb.tt
44
44
  - lib/generators/online_migrations/templates/background_data_migrations_remove_iteration_pause_default.rb.tt
45
+ - lib/generators/online_migrations/templates/background_migrations_change_status_default.rb.tt
45
46
  - lib/generators/online_migrations/templates/background_schema_migrations_change_unique_index.rb.tt
46
47
  - lib/generators/online_migrations/templates/change_background_data_migrations.rb.tt
47
48
  - lib/generators/online_migrations/templates/create_background_schema_migrations.rb.tt