Quinn Wilson
Quinn Wilson

Reputation: 8233

strategy for rails data and model migration

I need to migrate some data. I need to decrypt some fields (and that's no problem) but when I'm done I need to update the model to use a different strategy for the data access.

Is there a way to avoid two deployments? (One for the migration and one for the model update after the migration is complete?) I need to use the old model in the migration, but then I need the new one.

Upvotes: 0

Views: 67

Answers (1)

spickermann
spickermann

Reputation: 107142

You can add a dummy ActiveRecord model within your migration. Then your migration does not depend on the original model and its implementation anymore. That allows you to update the code in the original model.

Something like this:

class MigrateFooOnBar < ActiveRecord::Migration
  class Bar < ActiveRecord::Base
    def foo_migration
      self.foo = some_deprecated_code
    end
  end

  def up
    add_column :bars, :foo
    Bar.find_each do |bar|
      bar.foo_migrate
      bar.save!
    end
  end

# ...
end

But this not solve the core problem: A migration never runs at the exact same time when your application is deployed. When you deploy an application, the steps that does the migration runs before or after switching to the new code and the Rails app`s restart.

Depending on how long your migration takes - and it could run for minutes (and hours) on big tables - your app will face the situation in which it runs old code on a newer database schema, or has to run new code on an old database schema.

To avoid taking the app offline when running such migrations you will have to deploy multiple steps:

  1. Deploy a migration that add a new columns to the database
  2. Deploy the code changes that can run with both versions of the schema
  3. Run data transfermation and backfill tasks for old data
  4. Deploy code that removes backwards compability
  5. Run a migration removing the old columns

Upvotes: 2

Related Questions