web-dev-qa-db-ja.com

Railsのすべてのテーブルからすべてのデータを削除するにはどうすればよいですか?

Post.delete_allを実行してすべての投稿を削除できますが、すべての投稿、コメント、ブログなどを削除したい場合はどうすればよいですか?

すべてのモデルを反復処理し、delete_allメソッドを実行するにはどうすればよいですか?

60
Tom Lehman
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

コピー元の応答: SOに関する回答

80
Vlad Zloteanu

以下を使用して、より細かく制御できます。

rake db:drop:all

そして、移行を実行せずにデータベースを作成し、

rake db:create:all

その後、すべての移行を実行し、

rake db:migrate 

次のこともできます。

mysqladmin drop databasename
28
Sameer C

コマンドラインではなくコードからこれを実行しようとしている場合は、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

ただし、警告します。どちらも特に高速ではありません。可能な場合は、トランザクションテストを使用することをお勧めします。

23
James A. Rosen

空のテーブルの新鮮なセットで新鮮に始めたい場合は、最初にdb/schema.rbのスキーマの最新の定義があることを確認できます。

rake db:schema:dump

その後:

rake db:schema:load

一連の移行をすべて実行することなく、テーブルを削除してから再作成する効果があります。

17
KenB

justテーブル行を削除するより速い方法は、TRUNCATEコマンドを使用することです。

他の回答の多くは、行の削除とテーブルの削除の違いを無視しているようです。テーブルを削除すると、テーブルのデータとスキーマが破壊されます。つまり、テーブルを再作成するには追加の手順が必要です。 Sean McLearyの答えは私が見た中で最高だったので、出発点としてそれを使いました。ただし、TRUNCATEコマンドを利用する方がよいと思います。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
10
David J.

Rails db:purge

Rails 4.2.0.alphaのマスターブランチのActiveRecordに最近追加されました

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

10
gef

これはRails 4

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

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
4
vaughan

シードファイル(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は、ここでの仕事には多すぎます。これにより、データベースが完全に削除され、ゼロから再構築され、すべての移行などが実行されます。シードコマンドを実行する方が高速です。

4
Automatico

ここでは、Stack Overflowで database_cleaner gem に言及していないので見逃しています。

データベースクリーナーは、Rubyでデータベースをクリーニングするための一連の戦略です。元のユースケースは、テスト中にクリーンな状態を確保することでした。各戦略は少量のコードですが、データベースでテストするすべてのRuby=アプリで通常必要とされるコードです。

「戦略」とは、切り捨て、取引、削除という意味です。

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
3
David J.
# 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
3
grosser

アプリケーションまたはRails consoleで使用中にテーブルに触れずにデータのみを削除する場合:

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

このコードを使用すると、モデルを手動で参照したり、外部キー制約を使用したりする必要がなくなります(disable_referential_integrityのおかげ)。
ApplicationRecord.descendantsは、ActiveRecord :: Base.descendantsとは異なり、真のアプリケーションモデルのみを返します(ApplicationRecord、schema_migrations、ar_internal_metadataはこれ以上ありません)。

3
devoh

これは古い質問であることは知っていますが、これは誰かに役立つかもしれないと思いました。これは、データベースからすべてのデータを消去する非常に高速な方法です。

_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タスクよりもはるかに高速で効率的です。

ところで:データベース側で外部キー制約を強制している場合、これはおそらく失敗するでしょう。

2
Sean McCleary

Rails 6では、Rails db:truncate_allテーブルを削除せずにすべてのデータを削除します。

その後、dbをシードしたい場合は、Rails db:seed:replantすべてのデータとシードデータベースを切り捨てる

1
KahTim

私の50セント、dbのクリーニングと移行の再実行(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データベースをクリーンな状態にします。

1
Vitaly Dyatlov

@Vlad Zloteanuの答えに基づいて、ユーザーレコードとログインセッションをいくつかのメタ情報と一緒に保ちながら、すべてのテーブルを削除するバージョンを以下に示します。テーブルのリストを要件に合わせて自由に調整してください。

# lib/tasks/db/truncate.rake

namespace :db do
  desc 'Truncate all tables except users state and meta'
  task truncate: :environment do
    conn = ActiveRecord::Base.connection
    tables = conn.tables - %w[
      sessions
      users
      roles
      users_roles
      schema_migrations
      ar_internal_metadata
    ]
    tables.each { |t| conn.execute("TRUNCATE #{t}") }

    puts "Truncated tables\n================\n#{tables.sort.join("\n")}"
  end
end
0
Nic Nilov