代码之家  ›  专栏  ›  技术社区  ›  Blaine Lafreniere

我的Rails迁移将无法运行,我也无法部署我的Rails应用程序。我怎样才能重新开始?

  •  2
  • Blaine Lafreniere  · 技术社区  · 15 年前

    在我的Rails开发中的某个时刻,我开始在不使用Rails迁移的情况下进行数据库更改(例如删除或更改列/表)。所以现在,当我尝试从头开始部署Rails应用程序时,会出现错误。

    blaine@blaine-laptop ~/tmp/rbjacolyte $ rake db:migrate
    (in /home/blaine/tmp/rbjacolyte)
    ==  AddHashToTrack: migrating =================================================
    -- add_column(:tracks, :hash, :string)
    rake aborted!
    An error has occurred, all later migrations canceled:
    
    Mysql::Error: Table 'jacolyte_dev_tmp.tracks' doesn't exist: ALTER TABLE `tracks` ADD `hash` varchar(255)
    
    (See full trace by running task with --trace)
    

    在我使用原始SQL将生产和开发环境弄脏之后,如何将其与迁移同步?我想部署我的Rails应用程序而不出现数据库错误,我不想从头开始。


    生产和开发环境中的数据匹配,但迁移失败。我想要一种“从头开始”的方法。

    我可以简单地删除我所有的迁移,然后从现在开始使用迁移吗?

    4 回复  |  直到 15 年前
        1
  •  1
  •   edebill    15 年前

    快捷方式:手动为表示基线的时间戳向模式迁移添加一个条目。您可以在这之后添加迁移,只要它们对DB模式不做任何错误的假设,它们就可以正常运行。你不能向后迁移,但这不是一个大问题。

    更大的问题是,你将无法从零开始制作数据库,这将是一个长期的痛苦。

    解决方法是删除所有现有迁移,并创建一个创建现有架构的新迁移。手动删除schema_migrations表中的所有内容,并为此新迁移输入一个条目。之后,您可以创建基于这个新基线的新迁移,它们应该可以很好地应用。您应该能够以正常的方式引导新的数据库。

    只要您的直接SQL包含在Rails迁移中,就可以使用它。只要确保你同时实现了向上和向下的方法,你就应该是好的。实际上,我们已经采用原始SQL作为最佳实践,以避免稍后更改模型时出现问题。类似的东西

    Foo.create(:name => 'bar')
    

    似乎无害,直到用户模型被修改为

    validates_presence_of :baz
    

    此时,新的迁移将针对现有数据库运行,但是之前创建表并添加虚拟条目的迁移将失败,因为用户验证失败。只是使用

    execute("insert into foos (name) values ('bar')")
    

    只要以后的迁移正确地填充它们添加的任何新列,就可以正常工作。

        2
  •  1
  •   Veeti    15 年前

    也许你可以摆脱目前所有的迁移,然后使用 rake db:schema:dump 要创建一个新的schema.rb文件,并手动编辑生产数据库以反映到目前为止所做的更改吗?

        3
  •  0
  •   Community CDub    8 年前

    我喜欢Veeti的建议,并进行了修改:rake db:schema:dump,然后将该文件移到您的开发机器上。扁平化您的Rails迁移(请参见 this SO thread on that ,根据新的模式,去掉大部分迁移,重新工作迁移。

    在您的开发机器上运行这个,提交和部署。

        4
  •  0
  •   John Topley    15 年前

    如果现有的生产数据与开发数据库模式兼容,那么我将:

    1. 使用诸如 mysqldump
    2. 删除生产数据库
    3. 重新创建生产数据库
    4. 针对生产数据库运行迁移,指定version=0
    5. 从第一步创建的文件导入生产数据

    如果模式不兼容,那么您可能可以遵循此过程,但是您必须在第一步创建的文件中编辑SQL,以考虑模式差异。