Running a specific migration

Hi all,

I'm working on a large rails projects that has a lot of migration files (around 80). Through some development quirk, probably due to bad svn merging, my local database hasn't run migration 63. Is there a way to run this one file without having to roll back through all the later migrations, which would cause significant data loss?

Many thanks, Adam

% rake db:migration:up VERSION=63

Christian

Hi Christian,

That rake task didn't work for me. However, I googled "db:migrate:up" and found the task as part of the easily_migrate plugin. This was still not what I'm looking for - db:migrate:up just moves the db up one version, it cannot pick out an arbitrary migration to run. I added a few of my own tasks to achieve what I wanted - the code is pasted below if anyone needs it.

Basically I've written three tasks in addition to those from easily_migrate (Google Code Archive - Long-term storage for Google Code Project Hosting.):

db:specific:up VERSION=X Sets the database to version X-1, migrates to version X, resets to the current version

db:specific:down VERSION=X Sets the database to version X, migrates to version X-1, resets to the current version

db:specific:redo VERSION=X Sets the database to version X, migrates to version X-1, migrates back to version X, resets to the current version

I think these could be quite handy especially if you want to refactor your old migrations or if you've missed out a column somewhere and don't want to have to write a whole new migration for it. I hope it's helpful to someone!

namespace :db do   namespace :version do     desc "Manually set the schema version to an arbitrary number, used to recover from failed migration states. VERSION to be given"     task :set => :environment do      # eval "#{model_or_raise}.to_fixture(#{limit_or_nil_string})"         if ENV['VERSION'].blank?           raise "No version supplied Current Version: #{ActiveRecord::Migrator.current_version}. Set VERSION to change version."         else           puts "Current Version: #{ActiveRecord::Migrator.current_version}\r\n"           ActiveRecord::Migrator.set_schema_version(ENV['VERSION'])           puts "New version: #{ActiveRecord::Migrator.current_version}"         end     end   end

  namespace :migrate do     desc "Like db:migrate except it automatically targets the next version up"     task :up => :environment do       ActiveRecord::Migrator.migrate("db/ migrate/",ActiveRecord::Migrator.current_version.to_i + 1 )       puts "New version: #{ActiveRecord::Migrator.current_version}"     end

    desc "Like db:migrate except it automatically targets the next version down"     task :down => :environment do       ActiveRecord::Migrator.migrate("db/ migrate/",ActiveRecord::Migrator.current_version.to_i - 1 ) unless ActiveRecord::Migrator.current_version == 0       puts "New version: #{ActiveRecord::Migrator.current_version}"     end

    namespace :specific do       desc "Run a specific migration - sets the DB to the version below and migrates once"       task :up => :environment do         if ENV['VERSION'].blank?           raise "No version supplied Current Version: #{ActiveRecord::Migrator.current_version}. Set VERSION to change version."         else           current_version = ActiveRecord::Migrator.current_version           puts "Current Version: #{current_version}\r\n"

ActiveRecord::Migrator.set_schema_version(ENV['VERSION'].to_i - 1)           puts "Set to version: #{ActiveRecord::Migrator.current_version}"           ActiveRecord::Migrator.migrate("db/ migrate/",ActiveRecord::Migrator.current_version.to_i + 1 )           puts "Migrated to version: #{ActiveRecord::Migrator.current_version}"           ActiveRecord::Migrator.set_schema_version(current_version)           puts "Reset to version: #{ActiveRecord::Migrator.current_version}"         end       end

      desc "Run a specific migration - sets the DB to the version below and migrates once"       task :down => :environment do         if ENV['VERSION'].blank?           raise "No version supplied Current Version: #{ActiveRecord::Migrator.current_version}. Set VERSION to change version."         else           current_version = ActiveRecord::Migrator.current_version           puts "Current Version: #{current_version}\r\n"

ActiveRecord::Migrator.set_schema_version(ENV['VERSION'].to_i)           puts "Set to version: #{ActiveRecord::Migrator.current_version}"           ActiveRecord::Migrator.migrate("db/ migrate/",ActiveRecord::Migrator.current_version.to_i - 1 )           puts "Migrated to version: #{ActiveRecord::Migrator.current_version}"           ActiveRecord::Migrator.set_schema_version(current_version)           puts "Reset to version: #{ActiveRecord::Migrator.current_version}"         end       end

      desc "Redo a specific migration: run it's down method then it's up method"       task :redo => :environment do         if ENV['VERSION'].blank?           raise "No version supplied Current Version: #{ActiveRecord::Migrator.current_version}. Set VERSION to change version."         else           current_version = ActiveRecord::Migrator.current_version           puts "Current Version: #{current_version}\r\n"

ActiveRecord::Migrator.set_schema_version(ENV['VERSION'].to_i)           puts "Set to version: #{ActiveRecord::Migrator.current_version}"           ActiveRecord::Migrator.migrate("db/ migrate/",ActiveRecord::Migrator.current_version.to_i - 1 )           puts "Migrated to version: #{ActiveRecord::Migrator.current_version}"           ActiveRecord::Migrator.migrate("db/ migrate/",ActiveRecord::Migrator.current_version.to_i + 1)           puts "Migrated to version: #{ActiveRecord::Migrator.current_version}"           ActiveRecord::Migrator.set_schema_version(current_version)           puts "Reset to version: #{ActiveRecord::Migrator.current_version}"         end       end     end   end end

script/console

require 'db/migrate/20090418023701_add_product_messages.rb'

=> ["AddProductMessages"]

AddProductMessages.up

== AddProductMessages: migrating