Rails数据库迁移 - 如何删除一个表?

580

我添加了一张表,但现在不再需要它了。该如何删除这个表?

我已经运行了迁移,所以这个表已经存在于我的数据库中。我认为rails generate migration应该可以处理这个问题,但我还没有找到具体方法。

我尝试过:

rails generate migration drop_tablename

但那只生成了一个空的迁移。

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


1
由于rails generate migration具有用于生成创建表、添加或更改列等迁移代码的命令行选项,因此如果它还有一个删除表的选项就好了——但它没有。当然,编写“up”部分很简单——只需调用drop_table即可——但是“down”部分,重新生成表可能并不总是那么简单,特别是如果该表的模式在初始创建后被迁移更改了。也许应该建议Rails的开发人员添加这样一个选项是个好主意。 - Teemu Leisti
5
@TeemuLeisti 你觉得直接从schema.rb中复制当前表的定义如何?我经常这样做... - jasoares
1
@João Soares:好的,我想那样应该可以。不过,如果能够自动化这个过程就更好了,这样你只需要给出一个rake迁移创建命令,并附带一个表名作为参数,就可以生成所需的updown函数。 - Teemu Leisti
1
我在GitHub上为此打开了一个PR:https://github.com/rails/rails/pull/48729目前还不能撤销(我和@TeemuLeisti有相同的担忧),但也许其他人可以改进。 - knagode
24个回答

13
你可以按照指南中的方法回滚迁移: 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

通过这种方式,您也可以回滚并使用它来恢复任何迁移。


12

在不抛出异常或尝试重新创建现在为空的表的情况下,提供一种可实现迁移回滚、重做等操作的替代方案 -

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

9

你不能直接运行drop_table :table_name,而是可以通过运行rails g migration DropInstalls创建一个空的迁移。

然后,你可以把下面的代码添加到这个空迁移中:

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

然后在命令行中运行rails db:migrate,这应该会删除Installs表。

解决方案可以在这里找到。

请告诉我您是否有任何问题,我会尽快回答。 - Sarvar Khalimov

6

打开你的 Rails 控制台

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

5

ActiveRecord::Base.connection.drop_table :table_name

的意思是使用ActiveRecord库中的Base模块来操作数据库连接,并使用该连接删除名为"table_name"的数据表。

如果您正在开发环境中工作,这比得到更多赞同的答案要容易得多。 - Kai Durai

2

有用的文档

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

drop_table(table_name, **options)

选项:

:force 设置为 :cascade 以删除相关对象。默认值为 false。

:if_exists 如果表存在,则设置为 true 仅删除该表。默认值为 false。

示例:

  1. Create migration for drop table, for example we are want to drop User table

    rails g migration DropUsers
    
    Running via Spring preloader in process 13189
       invoke  active_record
       create    db/migrate/20211110174028_drop_users.rb
    
  2. Edit migration file, in our case it is db/migrate/20211110174028_drop_users.rb

    class DropUsers < ActiveRecord::Migration[6.1]
      def change
        drop_table :users, if_exist: true
      end
    end
    
  3. Run migration for dropping User table

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

2

我需要删除我们的迁移脚本以及相应的表格...


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"

2

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

从终端输入rails dbconsole

输入密码

在控制台中执行以下步骤:

USE db_name;

DROP TABLE table_name;

exit

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


您也可以输入“rails db”来打开它。 - ARK

1

运行

rake db:migrate:down VERSION=<version>

其中<version>是您要还原的迁移文件的版本号。

例如:

rake db:migrate:down VERSION=3846656238

0
最好的方法是:
rails g migration Drop_table_Users

然后执行以下操作

rake db:migrate

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接