如何跳过失败的迁移? (耙分贝:迁移)
我似乎无法找到一个选项或任何允许我跳过迁移。如何跳过失败的迁移? (耙分贝:迁移)
我知道你在想什么:“你永远不应该这样做......”
我需要跳过迁移,使那些没有在我的开发数据库中更改为特定用户记录。我不想更改迁移,因为它不属于我应该与之合作的来源。有没有办法跳过迁移或跳过失败的迁移?
在此先感谢!
我认为你应该修复有问题的迁移,以减少脆弱性,我猜想几个if
声明,也许rescue
就足够了。
但是,如果修改迁移确实不是一个选项,那么可以用各种方法来伪造它。首先,您可以评论迁移方法,运行rake db:migrate
,然后取消(或恢复)违规迁移。
您也可以伪造它的数据库,但这种欺骗的内部不推荐,除非你知道自己在做什么,你不介意手动修补的东西,当你(难免)犯了一个错误。数据库中有一个名为schema_migrations
的表,其中有一个varchar(255)
列,名为version
;此表由db:migrate
用于跟踪已应用哪些迁移。您所需要做的就是插入适当的version
值,并且rake db:migrate
会认为迁移已完成。找到问题的迁移文件:
db/migrate/99999999999999_XXXX.rb
然后进入你的数据库,并说:
insert into schema_migrations (version) values ('99999999999999');
其中99999999999999
当然,从迁移的文件名称中的数字。然后运行rake db:migrate
应该跳过该迁移。
我会在第三个选项之前选择第二个选项,我只包含“hack schema_versions
”选项以确保完整性。
而不是跳过,你可以让你的智能迁移的迁移,增加了一些IF它,所以你可以检查“特定用户”
是的,如果我已经写了迁移,我会这样做。但是我没有,我也不想真的想把我不应该碰到的部分源头搞砸,所以我最终只是暂时将它们剪掉。 – hmind 2012-01-10 23:12:34
这是做了一个关闭错误的好办法。
db:migrate:up VERSION=my_version
这将运行一个特定迁移的 “向上” 的行动。 (如果您需要它,也可以相反,只需将“up”替换为“down”)。因此,您可以通过这种方式运行将来的迁移,使旧的迁移(需要跳过)工作,或者运行每个迁移有选择地在它之前进行迁移
我也相信你可以重做迁移这种方式:
rake db:migrate:redo VERSION=my_version
我没有尝试过这种方法个人,所以因人而异。
有时,有必要重新填写schema_migrations
表绝对正确迁移 ... ONLY FOR为此我创造了这个方法
def self.insert_missing_migrations(stop_migration=nil)
files = Dir.glob("db/migrate/*")
timestamps = files.collect{|f| f.split("/").last.split("_").first}
only_n_first_migrations = timestamps.split(stop_migration).first
only_n_first_migrations.each do |version|
sql = "insert into `schema_migrations` (`version`) values (#{version})"
ActiveRecord::Base.connection.execute(sql) rescue nil
end
end
可以将其复制并粘贴到你想和任何模型用它从控制台
YourModel.insert_missing_migrations("xxxxxxxxxxxxxx")
(或者以某种方式)
其中"xxxxxxxxxxxxxx"
- 是您要停止插入其迁移前的时间戳(你可以让它空)
!只有当你完全理解你会得到什么结果时才使用它!
我有一个问题,我有一个迁移添加已经存在了,所以在我的情况,我不得不跳过此迁移以及表,因为我得到的错误
SQLite3::SQLException: table "posts" already exists: CREATE TABLE "posts"
我只是注释掉create table方法的内容,运行迁移,然后取消注释。这是一种手动的方式来解决它,但它的工作。见下:
这真是太好了!不敢相信我没有想到这一点。完全合作。 – helpse 2017-11-16 15:25:43
如果你必须这样做,你的应用程序的迁移是搞砸了!
插入所有丢失的迁移:
def insert(xxx)
ActiveRecord::Base.connection.execute("insert into schema_migrations (version) values (#{xxx})") rescue nil
end
files = Dir.glob("db/migrate/*")
files.collect { |f| f.split("/").last.split("_").first }.map { |n| insert(n) }
不一定。例如,如果您将生产数据库pg_restore复制到开发计算机,以解决生产数据的问题。当你没有所有的信息时,不要那么快地告诉别人他们做错了。 – 2016-09-08 18:21:19
@MikeBethany:在我的情况下,当我不得不使用它时,一切都变得非常混乱,我没有时间去理解它为什么会这样。关于pg_restore,它也应该恢复'schema_migrations'表,我猜对吧? – Dorian 2016-09-09 11:21:20
是的,当然,'schema_migrations'表只是数据库中的一个表。重新阅读你的标题我可以看到另一种解释。我原本是这样读的,“你没有正确写出你的迁移。”我认为你的意思是,“迁移有问题。”但这是显而易见的,因此这个问题,所以我认为“你搞砸了”的含义。我的错。 – 2016-09-11 15:20:52
雅,我只是说干就干,暂时切断了违规迁移。我个人会创建适当的If语句或只是检查生产环境,但显然,处理迁移的人不相信使用db:migrate while developing = P谢谢 – hmind 2012-01-10 23:11:25
@hmind:“处理迁移不相信在开发时使用db:migrate“。天啊。发布到您的生产系统必须是一个超级开心的乐趣! – 2012-01-10 23:30:28
幸运的是,我不处理这个要么是haha – hmind 2012-01-11 00:20:59