Удаление всех записей в таблице базы данных


Ответы:


249

Если вы ищете способ обойтись без SQL, вы можете использовать delete_all.

Post.delete_all

или с критериями

Post.delete_all "person_id = 5 AND (category = 'Something' OR category = 'Else')"

См. Здесь для получения дополнительной информации.

Записи удаляются без предварительной загрузки, что делает это очень быстро, но нарушает такие функции, как кеш счетчика, который зависит от кода rails, который будет выполняться при удалении.


13
Стоит отметить, что если у вас есть ассоциации с: зависимым =>: destroy или чем-либо, что нужно очистить после удаления, вам, вероятно, понадобится Post.destroy_all, хотя он намного медленнее. См. Apidock.com/rails/ActiveRecord/Base/destroy_all/class
Майкл Хеллейн

Этот ответ предполагает, что с таблицей связана модель. OP не указал этого - что, если таблица является таблицей соединения?
Тоби 1 Кеноби

1
@BradWerth, независимо от того, считается ли это хорошим или плохим стилем, я просто говорю, что возможно, что в базе данных Rails есть таблицы, которые не являются ActiveRecordмоделями. Вопрос касается удаления записи из «таблицы», и я просто указываю на предположение, содержащееся в ответе.
Тоби 1 Кеноби

У меня такой же запрос, что и у @ Toby1Kenobi.
nbsamar

30

Удалить через SQL

Item.delete_all # accepts optional conditions

Для удаления путем вызова метода уничтожения каждой модели (дорого, но гарантирует вызов обратных вызовов)

Item.destroy_all # accepts optional conditions

Все здесь


21

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

rake db:purge

вы также можете сделать это в тестовой базе данных

rake db:test:purge

5

Если вы имеете в виду удалить все экземпляры всех моделей, я бы использовал

ActiveRecord::Base.connection.tables.map(&:classify)
  .map{|name| name.constantize if Object.const_defined?(name)}
  .compact.each(&:delete_all)

1
Предпочитайте selectвсякий раз, когда вам нужно использовать выражение if внутри блока, так вам не придется связывать компактный метод для удаления элементов nil.
Себастьян Пальма

4
BlogPost.find_each(&:destroy)

Это отлично подходит для случаев нехватки памяти.
Epigene

Это единственный ответ, учитывающий потребление памяти.
Джон

2
Омг, зачем делать петлю для этого ... смысла нет. просто удалите все записи УДАЛИТЬ ИЗ таблицы, Model.delete_all
Imnl

@John, почему один-единственный запрос потребляет больше памяти, чем цикл запросов?
Imnl

@Imnl Каждая итерация создает новый экземпляр рассматриваемой модели, чтобы он мог обрабатывать обратные вызовы для метода удаления.
Джон

2

Если ваша модель называется BlogPost, это будет:

BlogPost.all.map(&:destroy)

это получит каждый BlogPost и загрузит его в массив Ruby перед их уничтожением.
hdgarrood

Зависит от ORM. Datamapper этого не сделает, потому что вы ничего не запрашиваете по каждой модели. А вот трассировка стека Mongoid, показывающая, что не выбирает никаких полей перед уничтожением каждой записи:MOPED: 127.0.0.1:27017 QUERY database=a_database collection=nothings selector={} flags=[:slave_ok] limit=0 skip=0 batch_size=nil fields=nil (0.3378ms)
stef

4
так как это вопрос рельсов, и спрашивающий не сказал, какой ORM он использует, мы должны предположить ActiveRecord
hdgarrood

2

Более свежий ответ в случае, если вы хотите удалить все записи в каждой таблице:

def reset
    Rails.application.eager_load!
    ActiveRecord::Base.descendants.each { |c| c.delete_all unless c == ActiveRecord::SchemaMigration  }
end

Подробнее об этом eager_load здесь .

После его вызова мы можем получить доступ ко всем потомкам ActiveRecord::Baseи применить delete_allко всем моделям.

Обратите внимание, что мы не очищаем таблицу SchemaMigration.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.