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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 21:33:26  来源:igfitidea点击:

How to delete all data from all tables in Rails?

ruby-on-railsactiverecord

提问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可以截断所有数据和种子数据库