Как удалить все данные из всех таблиц в Rails?
Я могу сделать Post.delete_all
чтобы удалить все мои сообщения, но что, если я хочу удалить все сообщения, комментарии, блоги и т. д.?
Как мне перебрать все мои модели и запустить delete_all
способ?
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