所以我做了这样的迁移
class AddDatetimeAttrToUsers < ActiveRecord::Migration
def change
change_column :users, :oauth_expires_at, :datetime
end
end
在我的本地环境中它工作得很好但是当我尝试
时heroku run rake db:migrate我收到错误
ERROR: column "oauth_expires_at" cannot be cast automatically to type timestamp without time zone
HINT: Specify a USING expression to perform the conversion.
当我搜索它时,我创建了一个新的迁移,这是使用更改更改属性的最佳做法。
class PutDatetimeFieldToUsersExpireAtColumn < ActiveRecord::Migration
def change
remove_column :users, :oauth_expires_at
add_column :users, :oauth_expires_at, :datetime
end
end
所以我尝试使用rake db:rollback来删除上次迁移并添加这个,告知我上次迁移是不可逆转的。
我的问题是,有没有办法实际回滚不可逆转的迁移,还是应该使用上面的新迁移进行迁移?
答案 0 :(得分:1)
您可以在迁移中定义up
和down
方法,而不是change
。
这是一个例子:
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
有了它,您就可以migrate
和rollback
之前不可逆转的迁移,就像正常迁移一样。
答案 1 :(得分:0)
似乎你需要指定当前类型的oauth_expires_at列,因为在回滚时Rails应该知道它来创建列。我的意思是:
remove_column :users, :oauth_expires_at, :string
答案 2 :(得分:0)
在您的示例中,您具有以下迁移文件:
class AddDatetimeAttrToUsers < ActiveRecord::Migration
def change
change_column :users, :oauth_expires_at, :datetime
end
end
您已经在开发环境中成功运行rake db:migrate
。您正在本地运行sqlite3,并在heroku上运行了PG,因此,您的change_column
在本地运行,但是在PG上失败,因为PG期望使用'using'语句。
此问题的解决方法,步骤1是编辑迁移文件,以按照上述Yohann的建议添加上下迁移。是的,即使您已经完成了此迁移,也应该这样做。
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
现在,您可以运行rake db:rollback
并避免不可逆的迁移错误,但前提是您没有附加的迁移。如果添加了其他迁移,则需要使用rake db:down VERSION=2018xxxxxxx
或rake db:rollback STEP=X
指定要返回的距离。
现在编辑迁移,使其与pg和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
现在,您应该能够耙db:migrate,推送到heroku,并且heroku运行rake db:migrate并继续前进。
最后,您应该让pg在本地工作以匹配您的生产环境。
答案 3 :(得分:-1)
如果您敢于丢失本地数据库中的数据,那么您可以通过以下步骤从不可逆转的迁移中恢复(通过丢失数据库数据):
1-首先删除您的数据库(假设您在开发环境中并且可以在此环境中删除数据库 - 您的测试数据库也将消失)
export RAILS_ENV=development
rake db:drop
2-重新加载模式文件:
rake db:schema:load
3-查看当前的迁移文件:
rake db:migrate:status
4-删除您要删除的迁移:
rake db:migrate:down VERSION=xxxxxx
rails destroy migration migration_name
5-然后,您可以使db:migrate迁移迁移。
rake db:migrate