【问题标题】:How to deploy migrations which remove models如何部署移除模型的迁移
【发布时间】:2014-06-07 14:54:11
【问题描述】:

我正在重构一个大型 Rails 应用程序,并对一个相当神秘的数据库结构进行大量更改。这包括删除大量表和模型,将数据放入数据库的其他部分。

为了使情况更清楚,假设我将数据从不必要的user_level 表移动到user 表中。到目前为止我所做的是:

  • 创建一个迁移,将access_level 列添加到user 表中,然后执行以下操作:

    User.all.each 做 |u| u.access_level = u.user_level.level 结束

  • 运行该迁移。将其检入 git。

  • user.rb 中删除user_level 模型和关联。检查到 git。
  • 创建一个删除user_level 表的迁移。运行它并将其检入 git。

这在开发中运行良好,但我不知道如何将其部署到生产服务器。目前我们相当不优雅的部署过程是在服务器上运行git pull,然后执行任何db:migrates 或类似的需要。但是如果我们这样做,当我们 git pull 更新代码到 head 然后尝试迁移时,UserLevel 模型不再存在,因此u.user_level.level 将失败。 (我愿意使用 Capistrano 之类的东西,但我不知道在这种情况下这是否会有所帮助。)

如果有一种方法可以依次检查每个 git 提交并在每个提交后运行 db:migrate,这一切都会完美无缺,但我不知道该怎么做,我敢肯定这一定是无论如何解决了问题。我该怎么做?

【问题讨论】:

    标签: ruby-on-rails git capistrano database-migration


    【解决方案1】:

    如何进行所有重构但立即删除模型或基础表?在单独的后续重构中执行此操作。

    【讨论】:

      【解决方案2】:

      是的,您可以使用git checkout 来获取给定提交的代码。例如:

      git checkout 4ddcd26652a9516aecff7a7e17f4c324bdb8f6dd
      

      4ddcd26652a9516aecff7a7e17f4c324bdb8f6dd 将是提交哈希。

      因此,对于您的情况,您可以执行 git pull 后跟 git checkout 以进行特定提交。运行迁移后,您可以移回 master。

      不过,您未来最好的选择是避免在迁移文件中直接使用模型(或任何其他外部依赖项)。一种方法是在迁移中定义模型(我只是在猜测模型的外观):

      class AddAccessLevelToUser < ActiveRecord::Migration
        class UserLevel < ActiveRecord::Base
          belongs_to :user
        end
      
        def up
          add_column :users, :access_level, :string
          UserLevel.each do |user_level|
            user = user_level.user
            user.access_level = user_level.access_level
            user.save!
          end
        end
      
        def down
          remove_column :users, :access_level
        end
      end
      

      您也可以简单地在迁移文件中编写 SQL。通过来自 Andrey Koleshko 的Change Migrations like a Boss 了解更多信息。

      删除对模型的依赖将防止人们试图拉下应用程序并从头开始运行所有迁移。

      【讨论】:

        【解决方案3】:

        由于在部署期间迁移之前正在运行代码更新,因此您删除的模型不再存在。

        我认为你可以使用纯 sql 命令代替 ruby​​ 代码User.all.each do |u| u.access_level = u.user_level.level end

        【讨论】:

        • 这在示例等简单情况下可以正常工作。在更复杂的情况下(不幸的是,我正在处理)我需要使用一些旧模型的方法将数据按摩成可序列化的格式 - 抱歉,应该提到这一点。 (我正在将价值 30 个表的技术规范数据永远不会更改 更改为 JSON 文档并将其推入一列。将所有关联序列化为单个文档需要一些工作,但不能用纯 SQL 完成。好吧,我确信它可以完成,但我不寒而栗......)
        • 哦,我明白了。我也不知道如何更改部署流程。我会尝试创建另一个分支并在没有删除部分的情况下挑选提交,然后使用此分支进行部署(仅用于 db)。迁移应该在临时分支中工作。之后,使用 master 分支再次部署以删除模型。
        猜你喜欢
        • 2021-06-02
        • 2018-04-06
        • 1970-01-01
        • 2017-10-17
        • 1970-01-01
        • 2022-06-17
        • 1970-01-01
        • 2014-07-19
        • 1970-01-01
        相关资源
        最近更新 更多