Rails DB迁移-如何删除表?


506

我添加了一个我认为自己需要的表,但现在不再计划使用它。我应该如何删除那张桌子?

我已经运行了迁移,因此该表位于数据库中。我认为rails generate migration应该可以解决这个问题,但是我还没有弄清楚该怎么做。

我试过了:

rails generate migration drop_tablename

但这只是一个空的迁移。

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


1
由于rails generate migration具有用于生成用于创建表,添加或更改列等的迁移代码的命令行选项,因此,如果它还具有删除表的选项,那就很好了,但事实并非如此。当然,编写up零件很简单-只需调用drop_table-但down重新生成表的零件可能并不总是那么简单,尤其是如果所讨论的表的架构已在最初创建后通过迁移进行了更改。也许有人应该向Rails的开发人员建议添加这样的选项将是一个好主意。
Teemu Leisti 2012年

3
@TeemuLeisti仅从schema.rb复制并粘贴当前表定义如何?我一直这样做...
jasoares 2013年

1
@JoãoSoares:好的,我想这可行。然而,这将是很好,如果这一过程可以实现自动化,这样你就可以只给一个rake迁移创建命令,一个表作为参数的名称,这将产生所需要的updown功能。
Teemu Leisti

Answers:


646

您将无法始终仅生成迁移就已经拥有所需的代码。您可以创建一个空的迁移,然后用所需的代码填充它。

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

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

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

drop_table :table_name

3
这也对我有用。但是,在完全迁移(从头开始安装)时,现在将首先创建表,然后再次将其删除。移除创建和删除迁移的过程安全吗?
berkes 2011年

2
对于删除表还是还原到以前的数据库模式,这是否更好?
威廉告诉2012年

3
如果您已经完成了该表的使用并且不打算再使用它,那么我就说删除它。如果不使用它,最好摆脱它。
皮特

6
@BederAcostaBorges的回答更不言而喻,准确无误
onerinas

2
如何也删除所有外键?其他表中还有指向要删除的表的列。
Martin Konicek '18年

352

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

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,它将为您删除表格。


14
向下迁移应用于重新创建要删除的表。
fflyer05 2014年

1
即使在开发中,也永远无法回滚这种迁移。仅将向下迁移留为空白会更好吗?
mhriess

1
这是更好的答案+ fflyer的评论
Zack Shapiro

2
@mjnissim和fflyer05是正确的,为了避免发生任何奇怪的事情,您应该在down方法中重新创建表。
Sebastialonso

4
删除表会删除所有数据,如果您使用该down方法重新创建它,则将无法恢复它,因此实际上不是适当的回滚。最好清楚地表明迁移是不可逆的,而不是错误地认为可以从中进行恢复。
vivi

314

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

至于迁移的代码,我只想引用Maxwell Holder的帖子 Rails迁移清单

不好-运行rake db:migrate然后rake db:rollback失败

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

良好-揭示迁移不可逆的意图

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"
Lencho Reyes

197

尽管此处提供的答案正常运行,但我想要更多“简单易懂”的东西,但我在这里找到了:链接 首先进入rails控制台:

$rails console

然后输入:

ActiveRecord::Migration.drop_table(:table_name)

完成了,为我工作!


在运行之前,模型仍然存在rails destroy model User
gm2008年

2
如果要永久删除表,请仅运行此命令。Rails将不会意识到这一下降。运行此命令后,迁移将中断。无法创建,删除... ETC。错误SQLite3 :: SQLException:没有这样的表:应计项目:DROP TABLE“ sometable”
Zee

36

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

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)

21
  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. 耙db:migrate

13

我认为,要完全“正式”,您需要创建一个新的迁移,并将drop_table放在self.up中。然后,self.down方法应包含所有代码以完全重新创建表。大概可以在创建迁移时从schema.rb中获取代码。

放一些代码来创建一个表,这看起来有点奇怪,您知道您不再需要该表了,但这将使所有迁移代码完整且“正式”,对吗?

我只是对需要删除的表进行了此操作,但老实说没有测试“下降”,并且不确定为什么会这样做。


1
奇怪,但看起来我也必须这样做。
digitalWestie 2011年

7
或者,您也可以raise ActiveRecord::IrreversibleMigration在self.down方法中使用:,以便您至少尝试回滚时,至少给自己一个错误/通知。
Steph Rose 2012年

1
我之所以会测试失败,是因为否则我会将未经测试的代码引入我的项目。如何重用原始迁移的up方法?我已经尝试过CreateMyTable.upActiveRecord::Migrator.run(:up, ActiveRecord::Migrator.migrations_paths, X)并且X是最初创建表的迁移,但是两者都不起作用-在这两种方法中,AR首先检查迁移是否已经应用,如果已迁移则自动跳过。`
艾萨克·贝特什

12

您可以简单地从Rails控制台中删除表。首先打开控制台

$ rails c

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

ActiveRecord::Migration.drop_table(:table_name)

替换table_name为要删除的表。

您也可以直接从终端放桌子。只需输入应用程序的根目录并运行此命令

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

10

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

  rails g migration drop_tablename

现在转到您的数据库/迁移并查找包含drop_tablename作为文件名的文件,然后对其进行编辑。

    def change
      drop_table :table_name
    end

那你需要跑

    rake db:migrate 

在您的控制台上。



8

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

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

8

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

rails c

类型

ActiveRecord::Migration.drop_table(:tablename)

这对我来说很有用。这将删除上一个表。别忘了跑步

rails db:migrate

7

打开Rails控制台

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


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"

1

最好的方法是

rails g migration Drop_table_Users

然后执行以下操作

rake db:migrate


1

如果有人正在寻找如何在SQL中做到这一点。

键入rails dbconsole从终端

输入密码

在控制台上

USE db_name;

DROP TABLE table_name;

exit

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


您也可以通过键入rails db
-ARK

0

如果要删除特定表,可以执行

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

否则,如果您要删除所有数据库,则可以执行

$rails db:drop

-1

放置表/迁移

运行:-$ rails生成迁移DropTablename

exp:-$ rails产生迁移DropProducts


-1

运行此命令:-

rails g migration drop_table_name

然后:

rake db:migrate

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

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

3
此答案是否会在现有的可接受答案中添加任何内容?如果没有,则无需发布。
汤姆·洛德

1
正如问题本身已经指出的那样,这会在rails 4.2中创建一个空迁移。
bert bruynooghe '17

这正是OP最初尝试的方式...应该删除此答案
webaholik

添加一个简单的答案不应该被低估。我想这仍然很重要。请对新用户好一些。
ARK

-2

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

rails db:rollback
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.