迁移魔术 - 与Ruby on Rails一起处理生产中的无效限制
#网络开发人员 #编程 #database #rails

我们所有人都在开发环境中的应用程序中添加了新的表和列。当事情出错时,我们放下桌子开始新鲜,没有伤害,没有犯规。但是,当我们在生产阶段遇到问题时会发生什么?那是挑战开始的时候。在这篇文章中,我们将解决涉及非限制的棘手迁移方案,并共享实用技巧,以避免在生产中丢失数据。所以搭扣,让我们潜入! ð

ð开发阶段幸福

当我在validateok.click应用程序上工作时,我需要将新列category添加到现有表ideas中。这是一个示例迁移:

class AddCategoryToIdeas < ActiveRecord::Migration[7.1]   
    def change     
        add_reference :ideas, 
                      :category, 
                      default: 'Tools', 
                      null: false, 
                      foreign_key: true, 
                      type: :uuid   
    end 
end

在开发环境中,运行此迁移很轻松,一切都按预期工作。但是生产呢? ð°

- 生产阶段障碍

在生产中,除非我们愿意失去所有东西,否则丢弃数据库不是一个选择 - 没人想要! ð±使用与我们在上述发展中所做的相同迁移步骤可能会导致错误,就像这样:

ActiveRecord::NotNullViolation: PG::NotNullViolation: ERROR: column "category_id" of relation "ideas" contains null values

错误之所以发生错误,是因为ideas表中的现有记录不具有category_id值,而不仅如此,而且我们设置了null: false约束。我们该怎么办来解决这个问题? ðρ

ð解决方案

不用担心!我们为您提供了完美的解决方案。让我们浏览生产优雅地处理此迁移所需的步骤

步骤1:删除默认值并将迁移分为两个部分

首先,从迁移中删除默认值“工具”,因为它应该是UUID而不是字符串。 这是我的错误,因为我没有注意我正在使用uuid。我是唯一的一个ðÖT,然后将迁移分为两个步骤:

  1. 在没有null: false约束的情况下添加category_id列,并使用默认类别回填现有想法。
  2. 最后,添加null: false约束。

这是更新的迁移文件:

class AddCategoryToIdeas < ActiveRecord::Migration[7.1]
  def up
    add_reference :ideas, :category, foreign_key: true, type: :uuid #1

    default_category = Category.find_or_create_by!(name: 'Tools')
    Idea.update_all(category_id: default_category.id)

    change_column_null :ideas, :category_id, false #2
  end

  def down
    remove_reference :ideas, :category
  end
end

步骤2:了解每个步骤的目的

  1. 添加无null: false约束的category_id列。这使我们能够在不违反非编号约束的情况下更新现有记录。
  2. 查找或创建名为“工具”的默认类别,并将其ID设置为所有现有想法的默认category_id。这确保了所有现有想法都有有效的category_id值。
  3. null: false约束添加到category_id列。现在,所有现有的想法都使用默认的category_id进行了更新,我们可以安全地执行非无效约束。
  4. 现在您可以自信地运行rails db:migrate

ð总结

,你有它,伙计们!多亏了这些步骤,我们在生产环境中优雅地处理了潜在的棘手迁移,而不会丢失任何数据ð。通过将迁移分为两个部分,更新现有记录,然后执行非挂钩约束,我们使应用程序更加健壮和可靠。

请记住,作为Rails Developers,必须考虑我们的DB迁移在开发和生产环境中的影响。有了一点远见和一些位置良好的表情符号ð,我们可以克服这些挑战并继续构建出色的应用。

一如既往,愉快的编码,直到下一次! ð