Как удалить все данные из всех таблиц в Rails?


Я могу сделать Post.delete_all чтобы удалить все мои сообщения, но что, если я хочу удалить все сообщения, комментарии, блоги и т. д.?

Как мне перебрать все мои модели и запустить delete_all способ?

15 55

15 ответов:

rake db:reset 

он воссоздает вашу таблицу из миграций.

Как было предложено в комментариях, более быстрый способ сделать это (но вы должны добавить новую задачу рейк) составляет:

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

ответ скопирован из: ответ на так.

вы можете иметь более точный контроль с:

rake db:drop:all

а затем создать базу данных без запуска миграции,

rake db:create:all

затем запустите все ваши миграции,

rake db:migrate 

вы также можете сделать:

mysqladmin drop databasename

Если вы пытаетесь сделать это из кода вместо командной строки, скажем, из 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

Я предупреждаю вас, что ни особенно быстро. Вам определенно лучше с транзакционными тестами, если вы можете.

Если вы просто хотите начать заново с нового набора пустых таблиц, вы можете сначала убедиться, что у вас есть актуальное определение схемы в db/schema.РБ:

rake db:schema:dump

и затем:

rake db:schema:load

который имеет эффект отбрасывания таблиц, а затем их повторного создания, не проходя через всю батарею миграций.

быстрый способ просто удалить строки таблицы-это использовать команду усечения.

многие другие ответы, похоже, игнорируют разницу между удалением строк и удаление таблицы. Удаление таблицы уничтожает табличные данные и схему; это означает, что вам нужны дополнительные шаги для повторного создания таблиц. Ответ Шона Маклири был лучшим, что я видел, поэтому я использовал его в качестве отправной точки. Тем не менее, я думаю, что лучше воспользоваться командой усечения, потому что она должна быть быстрее, и он также сбрасывает ключи автоматического приращения. Кроме того, используя 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

rake db:purge

недавно был добавлен в ActiveRecord в главной ветви rails 4.2.0.Альфа

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

вы можете перечислить все модели в seed-файле (seeds.РБ), и просто запустить

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 - это слишком много для вашего работа. Это полностью уничтожит вашу базу данных и перестроит ее с нуля, запустив все миграции и т. д. Чтобы запустить команду seed быстрее.

Это будет работать также для рельсов 4

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

мы были упущены здесь при переполнении стека за то, что не упомянули database_cleaner gem:

Database Cleaner-это набор стратегий для очистки вашей базы данных в 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
# 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

принятый ответ с 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

Если вы хотите удалить только данные, не касаясь таблиц при использовании его внутри вашего приложения или консоли 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).
ApplicationRecord.потомки возвращает только истинные модели приложений в отличие от ActiveRecord:: Base.потомки (нет больше ApplicationRecord, schema_migrations и ar_internal_metadata).

Я знаю, что это старый вопрос, но я думал, что это может быть полезно для кого-то. Это очень быстрый способ очистки всех данных из базы данных.

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 для очистки, миграции, сброса базы данных.

кстати: я уверен, что это, скорее всего, не удастся, если вы применяете ограничения внешнего ключа к базе данных сторона.

мои 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 чтобы ваша БД была в чистом состоянии.

основываясь на ответе @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