2013-04-16 167 views
25

我一直在分支之间在项目和交换他们每个人都有不同的迁移......这是情景:解决Rails孤立迁移的最佳方法是什么?

$耙分贝:迁移:状态

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 ********** 

问题是rake db:rollback完全不工作,因为丢失的文件...

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

顺便说一句,rake db:resetrake db:drop是不是一种选择,我无法从其他表数据丢失......

回答

40

我结束了解决这样的问题:

(1)转到某个迁移文件的树枝和回滚他们。当你有很多分支时,这是不平凡的,如果你试图合并它们,会导致许多冲突。所以我使用这个命令找出每个孤儿移植所属的分支。

所以,我需要找到最后一次迁移被修改的提交。

git log --all --reverse --stat | grep <LASTEST_ORPHAN_MIGRATION_ID> -C 10 

我把提交哈希并确定它属于哪个分支这样的:

git branch --contains <COMMIT_HASH> 

这样我就可以回到那个分支,做一回退,并重复这一过程对所有丢失的文件。

(2)运行迁移:检出您最终想要处理的分支并运行迁移,您应该很好。

故障排除

我也跑在某些情况下,孤儿上删除的分支迁移哪里。

为了解决这个问题,我使用与缺失文件相同的migration_id创建了虚拟迁移文件并将其回滚。在那之后,我就能够删除他们假人迁移,并有一个干净的迁移状态:)

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

delete from schema_migrations where version='<MIGRATION_ID>'; 
+6

很好的答案。请给我们更简单,更短,实用的方法首先不能持续! =]我一直都很紧张,直到哦。伪善。 – ahnbizcad

+6

你在哪里输入? '从schema_migrations删除版本='';' – ahnbizcad

+10

在您的数据库控制台中...您可以访问它键入: 'rails dbconsole' – Adrian

0

假设你使用Git,它应该是比较简单的抓住这些迁移并将其纳入当前的科。如果你有一个具体的承诺,你想从一个文件,你可以使用:

git checkout <commit hash> <file_name> 

(感谢this answer

或者,你可以从一个特定的分公司负责人检查了:

git checkout <branch name> -- <file_name> 

据此blog post

假设这些都是,实际上,数据库上运行的迁移版本,你应该很好t o回滚。

+0

谢谢回答。与此相关的问题是我正在与很多分支机构和开发人员一起开展一个大项目。所以,我不知道哪个分支有孤儿移民。我终于找到了方法(请参阅我的回答) – Adrian

0

您可以将两个分支合并回主服务器,以便您拥有所有可用的迁移。如果您真的不希望在那里进行迁移,但希望能够回滚,则可以编辑数据库中的schema_migrations表以删除与您没有文件的迁移相对应的行。但是,如果您随后使用不同的迁移切换到另一个分支,则会导致问题。

+0

将临时分支和回滚合并到一个好状态是一个好主意。但是,有些分支没有近似的祖先提交,所以在合并时它们将会产生大量的冲突......我解决了每个包含孤立迁移的分支回滚,然后再次返回到我的分支。 .. – Adrian

14

编辑:正如在评论中说,以下将下降数据库

已经为我工作更简单的方法(注意这个命令将删除数据库和所有数据都将丢失):

rake db:migrate:reset

..和然后:

rake db:migrate:status

孤儿(一个或多个)应消失。

+1

这样解决了我的孤儿问题。 – Livi17

+14

**注意:db:migrate:reset会丢失数据库,导致完全数据丢失!! ** – Phil

+1

请仔细阅读此消息 - 不要重置数据库,因为您将丢失所有数据。 “ –

12

迁移存储在您的数据库中。如果您想删除已放弃的迁移,请将其从数据库中删除。

举例Postgres的:

  1. 打开PSQL:

    psql 
    
  2. 连接到您的数据库:

    \c your_database 
    
  3. 如果你很好奇,显示schema_migrations:

    SELECT * FROM schema_migrations; 
    
  4. 如果你很好奇,检查被遗弃的迁移存在:

    SELECT version FROM schema_migrations WHERE version IN 
    ('20130320144219', '20130320161939', '20130320184628', '20130403190042', 
    '20130403195300', '20130403214000', '20130410194222'); 
    
  5. 删除:

    DELETE FROM schema_migrations WHERE version IN (<version list as above>); 
    

现在,如果运行bundle exec rake db:migrate:status,你会看到成功删除了孤立的迁移。

+1

这应该是被接受的答案。 – moveson

+0

谢谢,这真棒,并没有破坏我的分期数据。 –

0

如果迁移文件是真正丢失(如跑迁移,忘了回滚迁移,然后被删除迁移文件提交之前),我是能够重现失踪迁移如下:

  1. 回去git历史记录来获取schema.rb文件的副本并保存在git repo之外(git log; git checkout xxxxxx; cp schema.rb ~/schema_old.rb, git checkout master)
  2. 运行这两个文件一个差异,并复制迁移命令到,这名失踪的迁移ID相匹配的迁移文件(diff schema.rb ~/schema_old.rb > migration_file.rb; vi migration_file.rb
  3. 检查迁移状态和rollback(rake db:migrate:status; rake db:rollback; rake db:migrate:status;
相关问题