【问题标题】:Rails DB Migration - How To Drop a Table?Rails DB 迁移 - 如何删除表?
【发布时间】:2011-04-30 12:37:56
【问题描述】:

我添加了一个我认为我会需要的表格,但现在不再打算使用它。我应该如何删除该表?

我已经运行了迁移,所以该表在我的数据库中。我认为rails generate migration 应该能够处理这个问题,但我还没有弄清楚如何。

我试过了:

rails generate migration drop_tablename

但这只是产生了一个空迁移。

在 Rails 中删除表的“官方”方式是什么?

【问题讨论】:

  • 由于rails generate migration 具有用于生成用于创建表、添加或更改列等的迁移代码的命令行选项,如果它还具有删除表的选项会很好——但是它没有。当然,编写up 部分很简单——只需调用drop_table——但再次生成表的down 部分可能并不总是那么简单,尤其是在相关表的架构已更改的情况下通过初始创建后的迁移。也许有人应该向 Rails 的开发人员建议,添加这样一个选项是个好主意。
  • @TeemuLeisti 如何从 schema.rb 复制并粘贴当前表定义?我一直都这样……
  • @João Soares:好的,我想这行得通。但是,如果该过程可以自动化,那就太好了,这样您就可以只给出一个rake migration-creation 命令,并将表的名称作为参数,这将产生所需的updown功能。

标签: ruby-on-rails ruby-on-rails-3 migration rollback drop-table


【解决方案1】:

您并不总是能够简单地生成迁移以获取您想要的代码。您可以创建一个空迁移,然后使用您需要的代码填充它。

您可以在此处找到有关如何在迁移中完成不同任务的信息:

http://api.rubyonrails.org/classes/ActiveRecord/Migration.html

更具体地说,您可以查看如何使用以下方法删除表:

drop_table :table_name

【讨论】:

  • 这对我也有用。但是在完全迁移(从头开始安装)时,现在将首先创建该表,然后再次删除该表。删除创建和删除迁移是否安全?
  • 这里有任何关于删除表或恢复到以前的数据库模式是否更好的观点?
  • 如果您已经完成了该表并且不打算再使用它,我会说放弃它。如果它不被使用,最好摆脱它。
  • answer by @BederAcostaBorges 更加不言自明和准确
  • 如何同时删除所有外键?其他表中有指向要删除的表的列。
【解决方案2】:

首先使用您想要的任何名称生成一个空迁移。这样做很重要,因为它会创建适当的日期。

rails generate migration DropProductsTable

这将在 /db/migrate/ 中生成一个 .rb 文件,如 20111015185025_drop_products_table.rb

现在编辑该文件,使其如下所示:

class DropProductsTable < ActiveRecord::Migration
  def up
    drop_table :products
  end

  def down
    raise ActiveRecord::IrreversibleMigration
  end
end

我添加的唯一内容是drop_table :productsraise ActiveRecord::IrreversibleMigration

然后运行rake db:migrate,它会为你删除表格。

【讨论】:

  • 应该使用向下迁移来重新创建被删除的表。
  • 此迁移永远无法回滚,即使在开发中也是如此。将向下迁移留空会更好吗?
  • 这是更好的答案 + 飞人的评论
  • @mjnissim 和 fflyer05 是正确的,为了避免任何奇怪的事情,您应该在 down 方法中重新创建表。
  • 删除表会删除所有数据,如果您在down 方法中重新创建它,您将无法恢复它,因此它实际上不是正确的回滚。最好清楚地表明迁移是不可逆的,而不是给人一种可以从中恢复的错误感觉。
【解决方案3】:

手动编写您的迁移。例如。运行rails g migration DropUsers

至于迁移的代码,我只是引用 Maxwell Holder 的帖子Rails Migration Checklist

糟糕 - 运行 rake db:migrate 然后 rake db:rollback 将失败

class DropUsers < ActiveRecord::Migration
  def change
    drop_table :users
  end
end

GOOD - 表明迁移不应该是可逆的意图

class DropUsers < ActiveRecord::Migration
  def up
    drop_table :users
  end

  def down
    fail ActiveRecord::IrreversibleMigration
  end
end

更好 - 实际上是可逆的

class DropUsers < ActiveRecord::Migration
  def change
    drop_table :users do |t|
      t.string :email, null: false
      t.timestamps null: false
    end
  end
end

【讨论】:

  • 如果您从schema.rb 剪切并粘贴到块中,请不要忘记同时搜索schema.rb 以查找外键。然后将外键定义添加到drop_table 块中,例如:t.foreign_key "other_table"
  • 我使用了第三个选项,它对我来说非常好用。谢谢。
【解决方案4】:

警告:这样做需要您自担风险,正如 @z-atef 和 @nzifnab 正确指出的那样,Rails 不会意识到这些变化,您的迁移序列填充失败和您的架构将与您的同事不同。这只是作为本地修补开发的资源。


虽然此处提供的答案可以正常工作,但我想要一些更“直截了当”的东西,我在这里找到了它:link 首先进入rails控制台:

$rails console

然后输入:

ActiveRecord::Migration.drop_table(:table_name)

完成了,为我工作!

【讨论】:

  • 模型仍然存在,直到你运行rails destroy model User
  • 只有在你想永远摆脱桌子时才运行这个。 Rails 不会意识到这种下降。运行此命令后迁移中断。无法创建、删除...等。 ERROR SQLite3::SQLException: no such table: accruals: DROP TABLE "sometable"
  • 警告:不要这样做。您永远不应该直接从控制台对数据库执行 DDL 操作。您的结构文件将不知道进行了此更改,您的同事开发环境将与您自己的和生产环境不同,这只是一团糟。使用迁移。
【解决方案5】:

您需要使用以下命令创建一个新的迁移文件

rails generate migration drop_table_xyz

并在新生成的迁移文件(db/migration/xxxxxxx_drop_table_xyz)中写入drop_table代码

drop_table :tablename

或者,如果您想在不迁移的情况下删除表,只需通过以下方式打开 rails 控制台

$ rails c

并执行以下命令

ActiveRecord::Base.connection.execute("drop table table_name")

或者你可以使用更简化的命令

ActiveRecord::Migration.drop_table(:table_name)

【讨论】:

    【解决方案6】:
    1. rails g 迁移 drop_users
    2. 编辑迁移
        class DropUsers < ActiveRecord::Migration
          def change
            drop_table :users do |t|
              t.string :name
              t.timestamps
            end
          end
        end
    
    1. rake db:迁移

    【讨论】:

      【解决方案7】:

      简单而正式的方式是这样的:

        rails g migration drop_tablename
      

      现在转到您的 db/migrate 并查找包含 drop_tablename 作为文件名的文件并将其编辑到此。

          def change
            drop_table :table_name
          end
      

      那么你需要运行

          rake db:migrate 
      

      在您的控制台上。

      【讨论】:

        【解决方案8】:

        我无法使其与迁移脚本一起使用,因此我继续使用此解决方案。使用终端进入 rails 控制台:

        rails c
        

        类型

        ActiveRecord::Migration.drop_table(:tablename)
        

        它对我很有效。这将删除以前的表。不要忘记运行

        rails db:migrate
        

        【讨论】:

          【解决方案9】:

          我认为,要完全“官方”,您需要创建一个新的迁移,并将 drop_table 放在 self.up 中。然后 self.down 方法应包含完整重新创建表的所有代码。据推测,该代码可能只是在您创建迁移时从 schema.rb 中获取的。

          输入代码来创建一个您知道不再需要的表似乎有点奇怪,但这会使所有迁移代码保持完整和“官方”,对吧?

          我只是为需要删除的表执行此操作,但老实说并没有测试“下降”,也不知道我为什么会这样做。

          【讨论】:

          • 奇怪,但看起来我也必须这样做。
          • 或者你可以在 self.down 方法中使用:raise ActiveRecord::IrreversibleMigration,所以如果你尝试回滚,至少会给自己一个错误/通知。
          • 我会测试下,否则我会在我的项目中引入未经测试的代码。如何重用原始迁移的 up 方法?我已经尝试过CreateMyTable.upActiveRecord::Migrator.run(:up, ActiveRecord::Migrator.migrations_paths, X),其中 X 是最初创建表的迁移,但两者都不起作用——在这两种方法中,AR 首先检查迁移是否已经应用,如果有,则静默跳过它。 `
          【解决方案10】:

          您可以简单地从 rails 控制台删除一个表。 先打开控制台

          $ rails c
          

          然后将此命令粘贴到控制台中

          ActiveRecord::Migration.drop_table(:table_name)
          

          table_name 替换为您要删除的表。

          您也可以直接从终端删除表格。只需进入应用程序的根目录并运行此命令

          $ rails runner "Util::Table.clobber 'table_name'"
          

          【讨论】:

            【解决方案11】:

            引发异常或尝试重新创建现在为空的表的替代方法 - 同时仍启用迁移回滚、重做等 -

            def change
              drop_table(:users, force: true) if ActiveRecord::Base.connection.tables.include?('users')
            end
            

            【讨论】:

              【解决方案12】:

              您可以按照指南中的方式回滚迁移:

              http://guides.rubyonrails.org/active_record_migrations.html#reverting-previous-migrations

              生成迁移:

              rails generate migration revert_create_tablename
              

              编写迁移:

              require_relative '20121212123456_create_tablename'
              
              class RevertCreateTablename < ActiveRecord::Migration[5.0]
                def change
                  revert CreateTablename    
                end
              end
              

              这样你也可以回滚并可以用来恢复任何迁移

              【讨论】:

                【解决方案13】:

                打开你的 Rails 控制台

                ActiveRecord::Base.connection.execute("drop table table_name")
                

                【讨论】:

                  【解决方案14】:

                  ActiveRecord::Base.connection.drop_table :table_name

                  【讨论】:

                  • 如果您在开发环境中工作,这是一个比获得更多投票的答案更容易的解决方案
                  【解决方案15】:

                  如果有人正在寻找如何在 SQL 中执行此操作。

                  从终端输入rails dbconsole

                  输入密码

                  在控制台中做

                  USE db_name;

                  DROP TABLE table_name;

                  exit

                  请不要忘记从架构中删除迁移文件和表结构

                  【讨论】:

                  • 你也可以通过输入rails db来打开它
                  【解决方案16】:

                  我需要删除我们的迁移脚本以及表本身...

                  class Util::Table < ActiveRecord::Migration
                  
                   def self.clobber(table_name)   
                      # drop the table
                      if ActiveRecord::Base.connection.table_exists? table_name
                        puts "\n== " + table_name.upcase.cyan + " ! " 
                             << Time.now.strftime("%H:%M:%S").yellow
                        drop_table table_name 
                      end
                  
                      # locate any existing migrations for a table and delete them
                      base_folder = File.join(Rails.root.to_s, 'db', 'migrate')
                      Dir[File.join(base_folder, '**', '*.rb')].each do |file|
                        if file =~ /create_#{table_name}.rb/
                          puts "== deleting migration: " + file.cyan + " ! "
                               << Time.now.strftime("%H:%M:%S").yellow
                          FileUtils.rm_rf(file)
                          break
                        end
                      end
                    end
                  
                    def self.clobber_all
                      # delete every table in the db, along with every corresponding migration 
                      ActiveRecord::Base.connection.tables.each {|t| clobber t}
                    end
                  
                  end
                  

                  从终端窗口运行:

                  $ rails runner "Util::Table.clobber 'your_table_name'"
                  

                  $ rails runner "Util::Table.clobber_all"
                  

                  【讨论】:

                    【解决方案17】:

                    你能做的最好的方法是

                    rails g migration Drop_table_Users
                    

                    然后执行以下操作

                    rake db:migrate
                    

                    【讨论】:

                      【解决方案18】:

                      运行

                      rake db:migrate:down VERSION=<version>
                      

                      &lt;version&gt; 是您要恢复的迁移文件的版本号。

                      例子:-

                      rake db:migrate:down VERSION=3846656238
                      

                      【讨论】:

                        【解决方案19】:

                        您不能简单地运行drop_table :table_name,而是可以通过运行以下命令创建一个空迁移: rails g migration DropInstalls

                        然后您可以将其添加到该空迁移中:

                        class DropInstalls < ActiveRecord::Migration
                          def change
                            drop_table :installs
                          end
                        end
                        

                        然后在命令行中运行rails db:migrate,这将删除安装表 找到解决办法here

                        【讨论】:

                        • 如果您有任何问题,请告诉我,我们会尽快回复
                        【解决方案20】:

                        Helpful documentation

                        在迁移中,您可以通过以下方式删除表:

                        drop_table(table_name, **options)
                        

                        选项:

                        :force 设置为 :cascade 也可以删除依赖对象。默认为假

                        :if_exists 设置为 true 以仅在表存在时删除表。默认为假

                        例子:

                        1. 为删除表创建迁移,例如我们要删除User

                          rails g migration DropUsers
                          
                          Running via Spring preloader in process 13189
                             invoke  active_record
                             create    db/migrate/20211110174028_drop_users.rb
                          
                        2. 编辑迁移文件,在我们的例子中是db/migrate/20211110174028_drop_users.rb

                          class DropUsers < ActiveRecord::Migration[6.1]
                            def change
                              drop_table :users, if_exist: true
                            end
                          end
                          
                        3. 运行迁移以删除 User

                          rails db:migrate
                          
                          == 20211110174028 DropUsers: migrating ===============================
                          -- drop_table(:users, {:if_exist=>true})
                             -> 0.4607s
                          

                        【讨论】:

                          【解决方案21】:

                          删除表/迁移

                          运行:- $ rails 生成迁移 DropTablename

                          exp:- $ rails 生成迁移 DropProducts

                          【讨论】:

                            【解决方案22】:

                            如果你想删除一个特定的表,你可以这样做

                            $ rails db:migrate:up VERSION=[Here you can insert timestamp of table]
                            

                            否则,如果您想删除所有数据库,您可以这样做

                            $rails db:drop
                            

                            【讨论】:

                              【解决方案23】:

                              运行这个命令:-

                              rails g migration drop_table_name
                              

                              然后:

                              rake db:migrate
                              

                              或者如果您使用的是 MySql 数据库,那么:

                              1. 使用数据库登录
                              2. show databases;
                              3. show tables;
                              4. drop table_name;

                              【讨论】:

                              • 这个答案是否会在现有的、已接受的答案中添加任何内容?如果没有,则无需发布此内容。
                              • 这会在 Rails 4.2 中创建一个空迁移,如问题本身所述。
                              • 这正是 OP 最初尝试的内容......应该删除这个答案
                              • 添加一个简单的答案不值得被否决。我猜它仍然是相关的。请善待新用户。
                              【解决方案24】:

                              如果要从架构中删除表,请执行以下操作--

                              rails db:rollback
                              

                              【讨论】:

                              • 此命令只会撤消最后一个迁移命令。如果该命令是创建表,它将删除表。但除非您随后删除创建它的迁移文件,否则它将在下一个db:migrate 重新创建。保持迁移以便在其他地方复制很重要,尤其是在同时完成工作的情况下。使用db:rollback更改最终的数据库布局几乎肯定会毁掉很多人的工作。
                              猜你喜欢
                              • 1970-01-01
                              • 2017-08-03
                              • 1970-01-01
                              • 2015-12-07
                              • 2015-10-07
                              • 2018-09-22
                              • 2011-10-29
                              • 1970-01-01
                              • 2011-02-19
                              相关资源
                              最近更新 更多