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 命令,并将表的名称作为参数,这将产生所需的up
和down
功能。
【参考方案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 :products
和raise 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.up
和ActiveRecord::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>
<version>
是您要恢复的迁移文件的版本号。
例子:-
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 upgrade 迁移条目从模式迁移表中删除后
您如何编写 Rails 迁移以删除 schema.rb 中的 :id => false 选项?
Ruby on Rails + Postgres 迁移从每个 db 上的 schema.rb 中删除 enable_extension "pgcrypto":migrate