11

I happened to have deleted migrations and I don't want to revert these removed migrations.

This is what rake db:migrate:status produces:

 Status   Migration ID    Migration Name
------------------------------------------------------

   up     0               ********** NO FILE *********
   up     20150209023430  Create users 
   up     20150320184628  ********** NO FILE **********
   up     20150322004817  Add roles to users
   up     20150403190042  ********** NO FILE **********

rake db:migrate and rake db:rollback commands won't work because of the missing files.

I have no intentions to lose my data, so I don't want to use rake db:drop or rake db:reset.

What can I do to be able to perform migrate and rollback and how to get rid of the missing files?

Alex Nikolsky
  • 2,087
  • 6
  • 21
  • 36

3 Answers3

15

Alexander, you can get rid of those non-existing migrations. when you do rake db:migrate:status it will show as in the question.

so you can manually delete those versions from schema_migrations table using a pure sql query.

delete from schema_migrations where version = <version_number> by executing above query, it will be resolved.

Kushal
  • 342
  • 1
  • 7
  • 4
    or `ActiveRecord::SchemaMigration.where().delete_all` – Alex Nikolsky Jun 08 '16 at 13:41
  • 8
    @AlexanderShmatko Just to clarify, an array of versions can go in that `where` clause. Like so: ActiveRecord::SchemaMigration.where(version: [20170506145701,20170506145702,20170506145703]).delete_all – B. Bulpett May 18 '17 at 19:58
  • @mkrorfolk I tried using this to remove a migration but i'm getting error: `syntax error near unexpected token `version=20180412191332` full command used:`ActiveRecord::SchemaMigration.where(version=20180412191332).delete_all` can you help please? – Charlie Apr 13 '18 at 08:03
  • 1
    yes that's a syntax error. the `version` should be in a key format like `version: '20180412191332'` – Kushal Apr 16 '18 at 14:44
6

If you can find the migration's timestamp - the number part of the filename, then you can do:

rake db:migrate:down VERSION=20100905201547

You can find the timestamp using rake db:migrate:status

Edit - when the migration file has been irrecoverably deleted

You can get around this by creating an empty migration file, migrating, then rolling back twice. Then, make sure you delete the empty migration file before migrating again.

$ bundle exec rails g migration fix_rollback_error
$ bundle exec rails db:migrate
$ bundle exec rails db:rollback STEP=2
$ rm db/migrate/20200217040302_fix_rollback_error.rb
$ bundle exec rails db:migrate
Kaka Ruto
  • 4,581
  • 1
  • 31
  • 39
2

I'd already deleted a migration which I wanted to rollback.

So I:

  1. recreated an identical migration,
  2. named the migration file after the timestamp rails wanted,
  3. ran rake db:rollback STEP=1

and it worked.

stevec
  • 41,291
  • 27
  • 223
  • 311