Ruby-on-rails 如何从Rails中的所有表中删除所有数据?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1196172/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to delete all data from all tables in Rails?
提问by Tom Lehman
I can do Post.delete_allto delete all my posts, but what if I want to delete all posts, comments, blogs, etc.?
我可以Post.delete_all删除所有帖子,但是如果我想删除所有帖子、评论、博客等怎么办?
How do I iterate over all my models and run the delete_allmethod?
如何遍历所有模型并运行该delete_all方法?
回答by Vlad Zloteanu
rake db:reset
It recreates your table from migrations.
它从迁移中重新创建您的表。
As suggested in the comments, a faster way to do it (but you have to add a new rake task) is:
正如评论中所建议的那样,一种更快的方法(但您必须添加一个新的 rake 任务)是:
namespace :db do
desc "Truncate all tables"
task :truncate => :environment do
conn = ActiveRecord::Base.connection
tables = conn.execute("show tables").map { |r| r[0] }
tables.delete "schema_migrations"
tables.each { |t| conn.execute("TRUNCATE #{t}") }
end
end
Response copied from: answer on SO.
响应复制自:answer on SO。
回答by Sameer C
You can have finer control with:
您可以通过以下方式更好地控制:
rake db:drop:all
And then create the database without running the migrations,
然后在不运行迁移的情况下创建数据库,
rake db:create:all
Then run all your migrations,
然后运行所有迁移,
rake db:migrate
You can also do:
你也可以这样做:
mysqladmin drop databasename
回答by James A. Rosen
If you're trying to do this from code instead of the command line, say from a Test::Unit::TestCase#teardownmethod, you could do either
如果您尝试从代码而不是命令行执行此操作,例如从Test::Unit::TestCase#teardown方法中执行此操作,则可以执行以下任一操作
class MyTest < Test::Unit::TestCase
def teardown
ActiveRecord::Base.subclasses.each(&:delete_all)
end
end
or
或者
class MyTest < Test::Unit::TestCase
def teardown
Rake::Task['db:reset'].invoke
end
end
I warn you, though: neither is particularlyfast. You're definitely better off with transactional tests if you can.
不过,我警告你:两者都不是特别快。如果可以的话,使用事务测试肯定会更好。
回答by KenB
If you simply want to start fresh with a fresh set of empty tables, you can first ensure you have an up-to-date definition of the schema in db/schema.rb:
如果你只是想用一组新的空表重新开始,你可以首先确保你在 db/schema.rb 中有一个最新的架构定义:
rake db:schema:dump
and then:
进而:
rake db:schema:load
which has the effect of dropping tables and then re-creating them, without running through your entire battery of migrations.
这具有删除表然后重新创建它们的效果,而无需运行整个迁移电池。
回答by gef
rails db:purge
rails db:purge
has recently been added to ActiveRecord in the master branch of rails 4.2.0.alpha
最近在 Rails 4.2.0.alpha 的 master 分支中添加到 ActiveRecord
https://github.com/rails/rails/commit/e2f232aba15937a4b9d14bd91e0392c6d55be58d
https://github.com/rails/rails/commit/e2f232aba15937a4b9d14bd91e0392c6d55be58d
回答by David J.
A faster way to justdelete table rows is to use the TRUNCATE command.
仅删除表行的更快方法是使用 TRUNCATE 命令。
Many of the other answers seem to ignore the difference between deleting rows and dropping a table. Dropping a table destroys the table data and schema; meaning that you need extra steps to recreate the tables. Sean McLeary's answer was the best I saw, so I used it as a starting point. However, I think it is better to take advantage of the TRUNCATE command, because it should be faster and it also resets auto-increment keys. Also, using mapinstead of eachshortens the code a bit.
许多其他答案似乎忽略了删除行和删除表之间的区别。删除表会破坏表数据和模式;这意味着您需要额外的步骤来重新创建表。Sean McLeary 的回答是我看到的最好的,所以我用它作为起点。但是,我认为最好利用 TRUNCATE 命令,因为它应该更快,并且还会重置自动增量键。此外,使用map而不是each稍微缩短代码。
namespace :db do
desc "Truncate all tables"
task :truncate => :environment do
conn = ActiveRecord::Base.connection
tables = conn.execute("show tables").map { |r| r[0] }
tables.delete "schema_migrations"
tables.each { |t| conn.execute("TRUNCATE #{t}") }
end
end
回答by vaughan
Accepted answer with Postgres db:
Postgres db 接受的答案:
namespace :db do
desc "Truncate all tables"
task :truncate => :environment do
conn = ActiveRecord::Base.connection
postgres = "SELECT tablename FROM pg_catalog.pg_tables WHERE schemaname='public'"
tables = conn.execute(postgres).map { |r| r['tablename'] }
tables.delete "schema_migrations"
tables.each { |t| conn.execute("TRUNCATE \"#{t}\"") }
end
end
If there are foreign_keyerror like ActiveRecord::StatementInvalid (PG::FeatureNotSupported: ERROR: cannot truncate a table referenced in a foreign key constraint)
如果有foreign_key像这样的错误ActiveRecord::StatementInvalid (PG::FeatureNotSupported: ERROR: cannot truncate a table referenced in a foreign key constraint)
Then, CASCADEoption would help.
然后,CASCADE选项会有所帮助。
tables.each { |t| conn.execute("TRUNCATE \"#{t}\" CASCADE") }
回答by Rene
This will work also for Rails 4
这也适用于 Rails 4
(ActiveRecord::Base.connection.tables - ['schema_migrations']).each do |table|
table.classify.constantize.destroy_all
end
回答by devoh
If you want to delete only the data without touching the tables while using it inside your application or rails console :
如果在应用程序或 rails 控制台中使用数据时只想删除数据而不触及表:
Rails.application.eager_load!
ActiveRecord::Base.connection.disable_referential_integrity do
ApplicationRecord.descendants.each do |model|
model.delete_all
end
end
With this code, you don't have to bother with referencing manually your models and/or with foreign key constraints (thanks to disable_referential_integrity).
ApplicationRecord.descendants returns only true application models unlike ActiveRecord::Base.descendants (no more ApplicationRecord, schema_migrations and ar_internal_metadata).
使用此代码,您不必费心手动引用模型和/或外键约束(感谢 disable_referential_integrity)。
ApplicationRecord.descendants 只返回真正的应用程序模型,不像 ActiveRecord::Base.descendants(不再有 ApplicationRecord、schema_migrations 和 ar_internal_metadata)。
回答by KahTim
In Rails 6, you can do rails db:truncate_allto remove all data without dropping any tables.
在 Rails 6 中,您可以rails db:truncate_all删除所有数据而不删除任何表。
If you would like to seed your db after that, you could also do rails db:seed:replantto truncate all data and seed database
如果您想在此之后为您的数据库播种,您还rails db:seed:replant可以截断所有数据和种子数据库

