Irreversible migration, can it be fixed? - Rails 4

南笙酒味 提交于 2021-02-10 05:42:47

问题


So i made a migration like this

class AddDatetimeAttrToUsers < ActiveRecord::Migration
  def change
    change_column :users, :oauth_expires_at, :datetime
  end
end

on my local environment it works just fine but when i try

heroku run rake db:migrate i get an error

ERROR:  column "oauth_expires_at" cannot be cast automatically to type timestamp without time zone
HINT:  Specify a USING expression to perform the conversion.

When i searched it, i created a new migration like this as best practice for changing an attribute using change.

class PutDatetimeFieldToUsersExpireAtColumn < ActiveRecord::Migration
  def change
    remove_column :users, :oauth_expires_at
    add_column :users, :oauth_expires_at, :datetime
  end
end

so i tried to use rake db:rollback to delete last migration and add this one informing me that the last migration is irreversible.

my question is, is there a way to actually rollback on an irreversible migration or should i just migrate using the new migration above?


回答1:


In your example, you have the following migration file:

class AddDatetimeAttrToUsers < ActiveRecord::Migration
  def change
    change_column :users, :oauth_expires_at, :datetime
  end
end

You have already run rake db:migrate successfully in your dev environment. You are running sqlite3 locally and PG on heroku, and and as a result, your change_column works locally, but it fails on PG because PG expects a 'using' statement.

The fix this, step 1 is to edit your migration file to add an up and down migration as suggested by Yohann above. Yes, you should do this even though you have already raked this migration.

class AddDatetimeAttrToUsers < ActiveRecord::Migration
      def up
        change_column :users, :oauth_expires_at, :datetime
      end
      def down
        change_column :users, :oauth_expires_at, :time (or whatever type existed before datetime)
      end
    end

Now you can run rake db:rollback and avoid the irreversible migration error, but only if you HAVE NOT ADDED ADDITIONAL MIGRATIONS. If you have added additional migrations you will need to specify how far back to go using rake db:down VERSION=2018xxxxxxx or rake db:rollback STEP=X.

Now edit the migration so it plays nice with pg and sqlite3:

class AddDatetimeAttrToUsers < ActiveRecord::Migration
          def up
            change_column :users, :oauth_expires_at, :datetime, using: 'oauth_expires_at::datetime'
          end
          def down
            change_column :users, :oauth_expires_at, :time

        end

Now you should be able to rake db:migrate, push to heroku, and heroku run rake db:migrate and move on.

Finally, you should get pg working locally to match your production environment.




回答2:


You can define up and down methods instead of change in your migration. Here is an example:

def up
  connection.execute %(create or replace view name_of_the_db_view)
end

def down
  connection.execute %(drop view name_of_the_db_view)
end

With it you will be able to migrate and rollback the previously irreversible migration like it was a normal migration.




回答3:


It seems you need to specify a current type of oauth_expires_at column, because at rollback Rails should know it to create the column. I mean following:

remove_column :users, :oauth_expires_at, :string



回答4:


if you dare to lose your data on your local database then you can recover from irreversible migration(by losing your database data) by doing these steps:

1- first deleting your database(assuming that you are in the development environment and just ok to delete the database in this environment - your test database will also be gone)

export RAILS_ENV=development


rake db:drop

2- Reloading your schema file:

rake db:schema:load

3- To see your current migration files:

rake db:migrate:status

4- Delete the migration that you want to get rid of:

rake db:migrate:down VERSION=xxxxxx


rails destroy migration migration_name

5- Then you can make db:migrate to migrate your migrations.

rake db:migrate


来源:https://stackoverflow.com/questions/31867927/irreversible-migration-can-it-be-fixed-rails-4

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!