Löschen aller Datensätze in einer Datenbanktabelle

Antworten:

249

Wenn Sie nach einem Weg ohne SQL suchen, sollten Sie delete_all verwenden können.

Post.delete_all

oder mit einem Kriterium

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

Sehen Sie hier für weitere Informationen.

Die Datensätze werden gelöscht, ohne sie zuerst zu laden. Dies macht sie sehr schnell, unterbricht jedoch Funktionen wie den Zähler-Cache, der vom Rails-Code abhängt, der beim Löschen ausgeführt werden soll.

HakonB
quelle
13
Es ist erwähnenswert, dass Sie wahrscheinlich Post.destroy_all möchten, wenn Sie Assoziationen zu: abhängigen =>: zerstören oder etwas haben, das beim Löschen bereinigt werden muss - obwohl es viel langsamer ist. Siehe apidock.com/rails/ActiveRecord/Base/destroy_all/class
Michael Hellein
Bei dieser Antwort wird davon ausgegangen, dass der Tabelle ein Modell zugeordnet ist. Das OP hat dies nicht angegeben - was ist, wenn die Tabelle eine Join-Tabelle ist?
Toby 1 Kenobi
1
@BradWerth, ob es von einigen als guter oder schlechter Stil angesehen wird oder nicht, ich sage nur, dass es machbar ist, dass eine Rails-Datenbank Tabellen hat, die keine ActiveRecordModelle sind. Die Frage fragt nach dem Löschen eines Datensatzes aus einer 'Tabelle' und ich zeige nur oder die Annahme, die in der Antwort enthalten ist.
Toby 1 Kenobi
Ich habe die gleiche Anfrage wie bei @ Toby1Kenobi.
Nbsamar
30

Über SQL löschen

Item.delete_all # accepts optional conditions

Löschen durch Aufrufen der Zerstörungsmethode jedes Modells (teuer, stellt jedoch sicher, dass Rückrufe aufgerufen werden)

Item.destroy_all # accepts optional conditions

Alles hier

lebreeze
quelle
21

Wenn Sie die Datenbank vollständig leeren und nicht nur ein oder mehrere daran angehängte Modelle löschen möchten, haben Sie folgende Möglichkeiten:

rake db:purge

Sie können dies auch in der Testdatenbank tun

rake db:test:purge
KensoDev
quelle
5

Wenn Sie damit meinen, jede Instanz aller Modelle zu löschen, würde ich verwenden

ActiveRecord::Base.connection.tables.map(&:classify)
  .map{|name| name.constantize if Object.const_defined?(name)}
  .compact.each(&:delete_all)
dfaulken
quelle
1
Bevorzugen selectSie immer dann, wenn Sie einen if-Ausdruck innerhalb eines Blocks verwenden müssen. Auf diese Weise müssen Sie die kompakte Methode nicht verketten, um keine Elemente zu entfernen.
Sebastian Palma
4
BlogPost.find_each(&:destroy)
Philip
quelle
Dies ist ideal für Situationen mit geringem Arbeitsspeicher.
Epigene
Dies ist die einzige Antwort, die den Speicherverbrauch berücksichtigt.
John
2
Omg, warum sollte man dafür eine Schleife machen ... kein Sinn. Löschen Sie einfach alle Datensätze. DELETE FROM Tabelle, Model.delete_all
Imnl
@ John, warum verbraucht eine einzelne Abfrage mehr Speicher als eine Schleife von Abfragen?
Imnl
@Imnl Jede Iteration instanziiert eine neue Instanz des betreffenden Modells, damit die Rückrufe für die Löschmethode verarbeitet werden können.
John
2

Wenn Ihr Modell BlogPost heißt, wäre es:

BlogPost.all.map(&:destroy)
stef
quelle
Dadurch wird jeder einzelne BlogPost abgerufen und in ein Ruby-Array geladen, bevor er zerstört wird.
HDGARROOD
Kommt auf den ORM an. Datamapper würde das nicht tun, weil Sie nicht zu jedem Modell etwas anfordern. Und hier ist eine mongoide Stapelspur, die zeigt, dass sie keine Felder auswählt, bevor sie jeden Eintrag zerstört: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
Da es sich um eine Rails-Frage handelt und der Fragesteller nicht gesagt hat, welches ORM er verwendet, sollten wir
ActiveRecord
2

Neuere Antwort für den Fall, dass Sie alle Einträge in jeder Tabelle löschen möchten:

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

Weitere Informationen dazu eager_load hier .

Nach dem Aufruf können wir auf alle Nachkommen von zugreifen ActiveRecord::Baseund ein delete_allauf alle Modelle anwenden .

Beachten Sie, dass wir sicherstellen, dass die SchemaMigration-Tabelle nicht gelöscht wird.

Simon Ninon
quelle