如何从Rails中的所有表中删除所有数据?

时间:2009-07-28 19:14:49

标签: ruby-on-rails activerecord

我可以Post.delete_all删除我的所有帖子,但如果我想删除所有帖子,评论,博客等,该怎么办?

如何迭代我的所有模型并运行delete_all方法?

16 个答案:

答案 0 :(得分:80)

rake db:reset 

它从迁移中重新创建表。

正如评论中所建议的那样,更快的方法(但你必须添加一个新的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

answer on SO复制回复。

答案 1 :(得分:27)

您可以通过以下方式获得更好的控制权:

rake db:drop:all

然后在不运行迁移的情况下创建数据库

rake db:create:all

然后运行所有迁移

rake db:migrate 

你也可以这样做:

mysqladmin drop databasename

答案 2 :(得分:23)

如果您尝试从代码而不是命令行执行此操作,例如使用Test::Unit::TestCase#teardown方法,则可以执行此操作

class MyTest < Test::Unit::TestCase

  def teardown
    ActiveRecord::Base.subclasses.each(&:delete_all)
  end

end

class MyTest < Test::Unit::TestCase

  def teardown
    Rake::Task['db:reset'].invoke
  end

end

但是我警告你:特别快。如果可以,你肯定会更好地进行交易测试。

答案 3 :(得分:15)

如果您只想重新开始使用一组新的空表,您可以首先确保在db / schema.rb中拥有最新的模式定义:

rake db:schema:dump

然后:

rake db:schema:load

具有删除表然后重新创建它们的效果,而无需遍历整个迁移过程。

答案 4 :(得分:10)

删除表行的更快捷方法是使用TRUNCATE命令。

许多其他答案似乎忽略了删除行和删除表之间的区别。删除表会破坏表数据和模式;意味着您需要额外的步骤来重新创建表。 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

答案 5 :(得分:9)

rails db:purge

最近被添加到rails 4.2.0.alpha

的主分支中的ActiveRecord中

https://github.com/rails/rails/commit/e2f232aba15937a4b9d14bd91e0392c6d55be58d

答案 6 :(得分:4)

您可以列出种子文件(seeds.rb)中的所有模型,然后运行

rake db:seed

种子文件看起来像这样:

Model1.delete_all
Model2.delete_all
Model3.delete_all
Model4.delete_all
Model5.delete_all
Model6.delete_all
Model7.delete_all

...

rake db:reset对你的工作来说太过分了。这将完全扼杀您的数据库并从头开始重建,运行所有迁移等。运行种子命令更快。

答案 7 :(得分:4)

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

答案 8 :(得分:4)

这也适用于Rails 4

(ActiveRecord::Base.connection.tables - ['schema_migrations']).each do |table|
    table.classify.constantize.destroy_all
end

答案 9 :(得分:3)

我们在Stack Overflow中一直没有提及database_cleaner gem

  

Database Cleaner是一套用于在Ruby中清理数据库的策略。   最初的用例是确保测试期间的清洁状态。每个策略   是少量的代码,但是在任何ruby应用程序中通常需要的代码   用数据库进行测试。

根据'策略',Mabey先生的意思是:截断,交易和删除。

  

支持ActiveRecord,DataMapper,Sequel,MongoMapper,Mongoid和CouchPotato。

以下是Database Cleaner README的快速代码段:

require 'database_cleaner'
DatabaseCleaner.strategy = :truncation

# then, whenever you need to clean the DB
DatabaseCleaner.clean

答案 10 :(得分:3)

# fast truncation of all tables that need truncations (select is 10x faster then truncate)
# http://grosser.it/2012/07/03/rubyactiverecord-fastest-way-to-truncate-test-database/
def truncate_all_tables
  connection = ActiveRecord::Base.connection
  connection.disable_referential_integrity do
    connection.tables.each do |table_name|
      next if connection.select_value("SELECT count(*) FROM #{table_name}") == 0
      connection.execute("TRUNCATE TABLE #{table_name}")
    end
  end
end

答案 11 :(得分:3)

如果您想在应用程序或rails控制台中使用数据时仅删除数据而不触及表格:

Rails.application.eager_load!
ActiveRecord::Base.connection.disable_referential_integrity do
  ApplicationRecord.descendants.each do |model|
    model.delete_all
  end
end

使用此代码,您无需为手动引用模型和/或外键约束而烦恼(感谢disable_referential_integrity)。
与ActiveRecord :: Base.descendants不同,ApplicationRecord.descendants仅返回真正的应用程序模型(不再有ApplicationRecord,schema_migrations和ar_internal_metadata)。

答案 12 :(得分:3)

在Rails 6中,您可以执行rails db:truncate_all来删除所有数据而不会删除任何表。

如果您之后想要播种数据库,也可以执行rails db:seed:replant截断所有数据并播种数据库

答案 13 :(得分:2)

我知道这是一个老问题,但我认为这对某人有帮助。这是清除数据库中所有数据的一种非常快速的方法。

tables = []
ActiveRecord::Base.connection.execute("show tables").each { |r| tables << r[0] }
tables = tables - ["schema_migrations"]
tables.each do |table|
  ActiveRecord::Base.connection.execute("DELETE FROM #{table} WHERE 1 = 1")
end

我在after(:all)块中的某些规范中使用此技术。这比用于清除,迁移和​​重置数据库的任何Rails rake任务更快,更高效。

顺便说一句:如果您在数据库端强制执行外键约束,我很确定这可能会失败。

答案 14 :(得分:1)

我的50美分,用于清理数据库并能够再次运行迁移(如果您无法删除数据库,例如AWS RDS):

# get connection
conn = ActiveRecord::Base.connection
# find all tables needed to be removed
tables = conn.execute("SELECT * FROM pg_catalog.pg_tables WHERE schemaname='public' AND tablename<>'schema_migrations'").to_a.map { |r| r['tablename'] }
# remove all tables except schema_migrations
tables.each { |t| conn.execute("DROP TABLE #{t}") }
# clean migrations table
conn.execute("TRUNCATE TABLE schema_migrations")

现在您可以运行rake db:migrate让您的数据库处于干净状态。

答案 15 :(得分:0)

建立@Vlad Zloteanu的答案,这是一个删除所有表同时保留用户记录和登录会话以及一些元信息的版本。您可以根据自己的要求调整表格列表。

class ArtistPolicy < ApplicationPolicy
  def create?
    return false if user.banned?
    user.admin? || user.moderator? || user.contributor? && user.id == record.user_id
  end

  def update?
    create?
  end

  def destroy?
    create?
  end
end