解决Rails孤立迁移的最佳方法是什么?

Adr*_*ian 34 migration git ruby-on-rails rails-migrations ruby-on-rails-3

我一直在项目中的分支之间切换,每个分支都有不同的迁移...这是场景:

$ rake db:migrate:status

 Status   Migration ID    Migration Name
--------------------------------------------------
   ...
   up     20130307154128  Change columns in traffic capture
   up     20130311155109  Remove log settings
   up     20130311160901  Remove log alarm table
   up     20130320144219  ********** NO FILE **********
   up     20130320161939  ********** NO FILE **********
   up     20130320184628  ********** NO FILE **********
   up     20130322004817  Add replicate to root settings
   up     20130403190042  ********** NO FILE **********
   up     20130403195300  ********** NO FILE **********
   up     20130403214000  ********** NO FILE **********
   up     20130405164752  Fix ap hostnames
   up     20130410194222  ********** NO FILE **********
Run Code Online (Sandbox Code Playgroud)

rake db:rollback由于缺少文件,问题根本不起作用......

我该怎么办才能再次回滚并摆脱NO FILE消息?

顺便说一句,rake db:reset或者rake db:drop不是一个选项,我不能丢失其他表中的数据......

Adr*_*ian 51

我最终解决了这样的问题:

(1)转到具有迁移文件的分支并将其回滚.如果您有许多分支,如果您尝试合并它们会导致许多冲突,这并非易事.所以我使用这个命令找出每个孤儿迁移所属的分支.

所以,我需要找到上次修改迁移的提交.

git log --all --reverse --stat | grep <LASTEST_ORPHAN_MIGRATION_ID> -C 10
Run Code Online (Sandbox Code Playgroud)

我接受提交哈希并确定它属于哪个分支:

git branch --contains <COMMIT_HASH>
Run Code Online (Sandbox Code Playgroud)

然后我可以回到那个分支,做一个回滚并对所有丢失的文件重复这个过程.

(2)运行迁移:签出您最终要处理的分支并运行迁移,您应该好好去.

故障排除

我还运行了一些孤立迁移的情况,其中删除了分支.

为了解决这个问题,我使用与丢失文件相同的migration_id创建了虚拟迁移文件并将其回滚.之后,我能够删除它们的虚拟迁移并具有干净的迁移状态:)

另一种方法是直接从数据库中删除丢失的文件:

delete from schema_migrations where version='<MIGRATION_ID>';
Run Code Online (Sandbox Code Playgroud)

  • 在您的数据库控制台中...您可以输入它:`rails dbconsole` (15认同)
  • 很好的答案.请先给我们提供更简单,更短,更实用的方法!哦,我一直都很紧张,直到哦.伪善. (6认同)
  • 你在哪里打字?`从schema_migrations中删除version ='<MIGRATION_ID>';` (6认同)
  • @Adrian甚至更短,你可以输入rails db;) (3认同)
  • 如果您像我一样在运行 `rails db` 时遇到一些问题,您也可以从 Rails 控制台执行相同的操作,例如: `sql = "delete from schema_migrations where version='&lt;MIGRATION_ID&gt;';"` 然后 `ActiveRecord:: Base.connection.execute(sql)` (3认同)

med*_*dik 32

迁移存储在数据库中.如果要删除已放弃的迁移,请从db中删除它们.

Postgres的例子:

  1. 打开psql:

    psql
    
    Run Code Online (Sandbox Code Playgroud)
  2. 连接到您的数据库:

    \c your_database
    
    Run Code Online (Sandbox Code Playgroud)
  3. 如果你很好奇,请显示schema_migrations:

    SELECT * FROM schema_migrations;
    
    Run Code Online (Sandbox Code Playgroud)
  4. 如果您很好奇,请检查是否存在已放弃的迁移:

    SELECT version FROM schema_migrations WHERE version IN 
    ('20130320144219', '20130320161939', '20130320184628', '20130403190042',
     '20130403195300', '20130403214000', '20130410194222');
    
    Run Code Online (Sandbox Code Playgroud)
  5. 删除它们:

    DELETE FROM schema_migrations WHERE version IN (<version list as above>);
    
    Run Code Online (Sandbox Code Playgroud)

现在,如果您运行bundle exec rake db:migrate:status,您将看到已成功删除孤立迁移.

  • 谢谢,这太棒了,并没有破坏我的暂存数据。 (2认同)

sta*_*her 21

这是来自@medik 的 psql 答案的 rake 版本,它不会删除您的数据库或做任何疯狂的事情:

1) 找到您的孤立迁移版本:

rails db:migrate:status
Run Code Online (Sandbox Code Playgroud)

2)注意缺少的迁移版本并进入数据库控制台:

rails dbconsole
Run Code Online (Sandbox Code Playgroud)

3)现在手动从迁移表中删除版本:

delete from schema_migrations where version='[version_number]';
Run Code Online (Sandbox Code Playgroud)

  • 注意:如果只有 1 个版本号,请从版本中删除 [ ]。 (3认同)

小智 18

编辑:如评论中所述,以下将删除您的数据库

一种更简单的方法对我有用(请注意,此命令将丢弃数据库,所有数据都将丢失):

rake db:migrate:reset

..然后:

rake db:migrate:status

孤儿应该消失.

  • **注意:db:migrate:reset将丢弃数据库,导致数据完全丢失!!** (20认同)
  • "我并不总是吹走我的数据库,但是当我这样做时,这是因为我没有首先阅读SO评论." (15认同)
  • 来自轨道的Nuking确保消灭孤儿. (5认同)
  • 请阅读上面的消息 - 不要重置数据库,因为您将丢失所有数据. (3认同)
  • 什么样的施虐狂才会赞成这个答案?不要执行此操作来删除孤立的迁移。 (2认同)

Evs*_*dim 5

创建新文件,其名称类似于 20130320144219_migration_1 将一些空白代码放入

class Migration1 < ActiveRecord::Migration 
  def change; end 
end 
Run Code Online (Sandbox Code Playgroud)

并运行命令rails db:migrate:down VERSION= 20130320144219 ,最后 - 删除此文件