【问题标题】:How to fix database that has many tables without matching migrations with Rails如何修复具有许多表而不匹配 Rails 迁移的数据库
【发布时间】:2017-02-05 09:11:48
【问题描述】:

我正在帮助一个朋友的 rails 应用程序。他们有一个数据库,其中包含许多表,这些表是使用 SQL 手动添加的,而不是使用 rails 迁移。他们已经开始正常添加迁移,但他们需要让两者重新同步。

如果我们现在添加迁移,它们会出错,因为这些表/列已经存在。如果我们不考虑它们,人们必须使用 db:schema:load 来启动和运行,然后按名称一次运行一个迁移以避免错误。我们希望避免这种情况,而是回到健康的状态。

有谁知道让迁移与数据库同步的更好方法?我们必须在不丢失任何数据的情况下执行此操作。

【问题讨论】:

    标签: mysql ruby-on-rails ruby database-migration rails-migrations


    【解决方案1】:

    备份表中不存在的内容后 迁移,你可以:

    • DROP 那些表;
    • 为每个已删除的表创建迁移;
    • 运行每个已创建的迁移;
    • 手动重新填充使用迁移创建的表。

    这样您就不会遇到迁移问题。 如果您没有他们的相关数据,请立即DROP他们。

    【讨论】:

      【解决方案2】:

      这是question with the same problem(没有投票赞成关闭你的重复,因为旧的没有接受的答案):

      解决办法是:

      1. 首先在 database.yml 中引用您现有的 MySQL 数据库。
      2. 运行rake db:schema:dump生成schema.rb文件
      3. create_table 方法从 schema.rb 粘贴到新的迁移中,瞧!

      为避免任何不一致,您可以随时检查表是否已经存在,如果是,则完全跳过迁移:

      class CreateTable < ActiveRecord::Migration
        def change
          unless ActiveRecord::Base.connection.table_exists?('table_name')
            create_table :table_names do |t|
              # some columns
            end
          end
        end
      end
      

      【讨论】:

      • 似乎这会在 prod 中失败,因为它会尝试创建这些表并且它们已经存在,不是吗?我添加了一句话来澄清我们必须在不丢失数据的情况下这样做。
      • @williamcodes 你可以随时使用ActiveRecord::Base.connection.table_exists? 'table_name' 来检查而不是运行迁移
      • 这是有道理的。你的意思是在迁移文件中使用它作为条件来防止它被运行两次,对吧?您可以将其添加到您的答案中吗?
      • 澄清一下,db:schema:dump 从实际存在于 MySQL 数据库中的表中生成其 schema.rb,因此我们必须在连接到 prod 时运行此转储,对吗?
      • @williamcodes 对,db:schema:dump 创建基于数据库的schema.rb。但是,只要您的本地数据库中有表(甚至是空的),您就不必在运行时连接到生产环境 - 它只关心表和列,而不关心内容
      猜你喜欢
      • 2017-05-02
      • 2011-04-15
      • 1970-01-01
      • 1970-01-01
      • 2017-07-19
      • 1970-01-01
      • 1970-01-01
      • 2016-10-24
      • 1970-01-01
      相关资源
      最近更新 更多