Rails DB 迁移 - 如何删除表?

Posted

技术标签:

【中文标题】Rails DB 迁移 - 如何删除表?【英文标题】:Rails DB Migration - How To Drop a Table? 【发布时间】: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功能。 【参考方案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】:
    rails g 迁移 drop_users 编辑迁移
    class DropUsers < ActiveRecord::Migration
      def change
        drop_table :users do |t|
          t.string :name
          t.timestamps
        end
      end
    end
    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 以仅在表存在时删除表。默认为假

例子:

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

    rails g migration DropUsers
    
    Running via Spring preloader in process 13189
       invoke  active_record
       create    db/migrate/20211110174028_drop_users.rb
    

    编辑迁移文件,在我们的例子中是db/migrate/20211110174028_drop_users.rb

    class DropUsers < ActiveRecord::Migration[6.1]
      def change
        drop_table :users, if_exist: true
      end
    end
    

    运行迁移以删除 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 数据库,那么:

    使用数据库登录 show databases; show tables; drop table_name;

【讨论】:

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

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

rails db:rollback

【讨论】:

此命令只会撤消最后一个迁移命令。如果该命令是创建表,它将删除表。但除非您随后删除创建它的迁移文件,否则它将在下一个db:migrate 重新创建。保持迁移以便在其他地方复制很重要,尤其是在同时完成工作的情况下。使用db:rollback更改最终的数据库布局几乎肯定会毁掉很多人的工作。

以上是关于Rails DB 迁移 - 如何删除表?的主要内容,如果未能解决你的问题,请参考以下文章

如何从现有迁移文件中删除脚本 rails

在 rails upgrade 迁移条目从模式迁移表中删除后

您如何编写 Rails 迁移以删除 schema.rb 中的 :id => false 选项?

Ruby on Rails + Postgres 迁移从每个 db 上的 schema.rb 中删除 enable_extension "pgcrypto":migrate

DB2如何快速删除大量记录

如何回滚到以前的迁移并删除架构中的表和列?