Wie lösche ich alle Zeilen in einer Tabelle mit Eloquent?

135

Meine Vermutung war, die folgende Syntax zu verwenden:

MyModel::all()->delete();

Das hat aber nicht funktioniert. Ich bin sicher, es ist super einfach, aber ich habe nach Dokumentation zu diesem Thema gesucht und kann sie nicht finden!

Pete
quelle

Antworten:

278

Der Grund MyModel::all()->delete()dafür ist, dass all()die Abfrage tatsächlich ausgelöst wird und eine Sammlung eloquenter Objekte zurückgegeben wird.

Sie können die Methode "Abschneiden" verwenden. Dies funktioniert für Laravel 4 und 5:

MyModel::truncate();

Dadurch werden alle Zeilen aus der Tabelle entfernt, ohne dass einzelne Zeilenlöschungen protokolliert werden.

bilalq
quelle
1
Ich habe meiner Frage eine Laravel 3-Lösung für zukünftige Leser hinzugefügt.
Pete
39
Nett. Dies funktioniert auch auf Laravel 5, wenn sich 2016 jemand anderes hier
googelt
14
Hinweis: truncate () setzt auch alle AUTO_INCREMENT-Zähler zurück (beachten Sie auch, dass Sie Tabellen mit Fremdschlüsseleinschränkungen nicht abschneiden können.)
William Turrell
10
Zu Ihrer Information: Turncate löst keine Löschereignisse aus.
Fusion
1
Wenn Sie wirklich verwenden möchten MyModel::all()->delete(), verwenden Sieforeach (MyModel::all() as $e) { $e->delete() }
Ema4rl
70

Laravel 5.2+ Lösung.

Model::getQuery()->delete();

Nehmen Sie einfach den zugrunde liegenden Builder mit dem Tabellennamen und machen Sie was auch immer. Könnte nicht aufgeräumter sein.

Laravel 5.6 Lösung

\App\Model::query()->delete();
Yauheni Prakopchyk
quelle
9
Falls jemand anderes war verwirrt darüber , warum dies funktioniert, die Modellklasse nach vorne Methoden zum Builder über die __call magische Methode hier . Da die Modellklasse selbst über eine Löschmethode verfügt, ruft der Aufruf von Model :: delete () die Modellmethode auf, wenn Sie die Builder-Methode wirklich möchten. Um den Builder explizit abzurufen, können Sie getQuery () verwenden.
KevinAlbs
Dies löscht auch keine verwandten Tabellen, wenn Sie das möchten.
Terje Nesthus
Es wird das Löschen aller Datensätze erzwingen, unabhängig davon, ob das weiche Löschen
aktiviert
Model :: whereNotNull ('id') -> delete (); - wird Soft Delete
ausführen,
61

Sie können verwenden, Model::truncate()wenn Sie deaktivieren foreign_key_checks(ich nehme an, Sie verwenden MySQL).

DB::statement("SET foreign_key_checks=0");
Model::truncate();
DB::statement("SET foreign_key_checks=1");
Fortex
quelle
2
In Laravel 4 verwenden Sie DB :: unvorbereitet ()
swdev
Sie können auch Schema :: disableForeignKeyConstraints () verwenden. & Schema :: enableForeignKeyConstraints ();
Eleazar Resendez
32

Ich habe gesehen, dass beide Methoden in Seed-Dateien verwendet wurden.

// Uncomment the below to wipe the table clean before populating

DB::table('table_name')->truncate();

//or

DB::table('table_name')->delete();

Auch wenn Sie den ersten nicht verwenden können, wenn Sie Fremdschlüssel festlegen möchten .

Eine Tabelle, auf die in einer Fremdschlüsseleinschränkung verwiesen wird, kann nicht abgeschnitten werden

Es könnte also eine gute Idee sein, die zweite zu verwenden.

giannis christofakis
quelle
2
deleteist offensichtlich nicht dasselbe wie als truncateob.
Joel Mellon
2
@sudopeople Es wäre wirklich hilfreich, auf den Unterschied hinzuweisen. Ich könnte es auch zu meiner Antwort hinzufügen .
Giannis Christofakis
4
TRUNCATE kann nicht in einer Transaktion verwendet werden, da es nicht von ROLLBACK betroffen ist. In diesem Fall kann dies mit (new MyModel) -> newQuery () -> delete () erreicht werden.
Hammurabi
12

Es gibt einen indirekten Weg:

myModel:where('anyColumnName', 'like', '%%')->delete();

Beispiel:

User:where('id', 'like' '%%')->delete();

Informationen zum Builder für Laravel-Abfragen: https://laravel.com/docs/5.4/queries

Rejaul
quelle
1
@aschipfl eigentlich nicht viel zu erklären. Der Code führt die SQL aus, DELETE FROM users WHERE id LIKE '%%'die mit allen Zeilen in der Tabelle übereinstimmt, und löscht so alles.
Hkan
Das hat mich auf den Weg gebracht. Am Ende habe ich ein anderes Modell gezupft (), um ein Array der benötigten IDs zu erhalten, und dann dieses Array verwendet, um alle Datensätze mit der folgenden whereInMethode aus meinem Modell zu löschen : $itemsAllContentIDs = Item::where('user_id', $userId)->pluck('item_content_id')->all(); ItemsContent::whereIn('id', $itemsAllContentIDs)->delete();
Keith DC
9

Ich wollte eine weitere Option für diejenigen hinzufügen, die über Google zu diesem Thread gelangen. Ich musste dies erreichen, wollte aber meinen Auto-Inkrement-Wert beibehalten, der truncate()zurückgesetzt wird. Ich wollte auch DB::nichts verwenden , weil ich direkt vom Modellobjekt aus arbeiten wollte. Also ging ich damit:

Model::whereNotNull('id')->delete();

Natürlich muss die Spalte tatsächlich vorhanden sein, aber in einem standardmäßigen, sofort einsatzbereiten eloquenten Modell ist die idSpalte vorhanden und niemals null. Ich weiß nicht, ob dies die beste Wahl ist, aber es funktioniert für meine Zwecke.

Lookitsatravis
quelle
Model::delete();wird das gleiche erreichen.
Leng
5
Model::delete()Wirft leider eine Ausnahme Non-static method Illuminate\Database\Eloquent\Model::delete() should not be called statically, zumindest in Laravel 5.0.
Dave James Miller
6

Ich konnte nicht verwenden, Model::truncate()da es Fehler wäre:

SQLSTATE [42000]: Syntaxfehler oder Zugriffsverletzung: 1701 Eine Tabelle, auf die in einer Fremdschlüsseleinschränkung verwiesen wird, kann nicht abgeschnitten werden

Und Model::delete()funktioniert leider nicht (zumindest in Laravel 5.0):

Nicht statische Methode Illuminate \ Database \ Eloquent \ Model :: delete () sollte nicht statisch aufgerufen werden, vorausgesetzt, dies ist aus einem inkompatiblen Kontext

Aber das funktioniert:

(new Model)->newQuery()->delete()

Dadurch werden alle Zeilen sanft gelöscht, wenn Sie das Soft-Löschen eingerichtet haben. Um alle Zeilen vollständig zu löschen, einschließlich der weich gelöschten, können Sie Folgendes ändern:

(new Model)->newQueryWithoutScopes()->forceDelete()
Dave James Miller
quelle
4

Der beste Weg, um diesen Vorgang Laravel 3auszuführen, scheint die Verwendung der FluentSchnittstelle zum Abschneiden der Tabelle zu sein, wie unten gezeigt

DB::query("TRUNCATE TABLE mytable");
Pete
quelle
2

Sie können diesen Einzeiler ausprobieren, der auch weiche Löschvorgänge bewahrt:

Model::whereRaw('1=1')->delete();
jfeid
quelle
1

einfache Lösung:

 Mymodel::query()->delete();
Ali Filali
quelle
0

Ähnlich wie bei Travis Vignons Antwort benötigte ich Daten aus dem beredten Modell, und wenn die Bedingungen korrekt waren, musste ich das Modell entweder löschen oder aktualisieren. Am Ende erhielt ich das von meiner Abfrage zurückgegebene Minimum und Maximum (falls ein anderes Feld zur Tabelle hinzugefügt wurde, das meinen Auswahlkriterien entspricht) zusammen mit den ursprünglichen Auswahlkriterien, um die Felder über eine unformatierte SQL-Abfrage (as) zu aktualisieren im Gegensatz zu einer beredten Abfrage pro Objekt in der Sammlung).

Ich weiß, dass die Verwendung von rohem SQL gegen die schöne Code-Philosophie von Laravel verstößt, aber es wäre schwierig, möglicherweise Hunderte von Abfragen anstelle einer zu ertragen.

Sidney
quelle
0

Kann ein Schleife auch ..

$collection = Model::get();

foreach($collection as $c) {

$c->delete();

}
Sam Solomon
quelle
Technisch ja ... aber IMO scheint das ein bisschen unnötig zu sein, da es bessere Einzelabfrageoptionen gibt.
Pete
@ Pete ich weiß .. andere gaben bereits ihre Antworten ... ich habe versucht, die andere mögliche Methode zu beantworten ..
Sam Solomon
1
Dies funktioniert tatsächlich für mich, da ich vorhabe, die Modelle in der Sammlung basierend auf bestimmten Regeln zu archivieren, sie aber auch aus dieser täglich aktiven Tabelle zu löschen.
James Perih
0

Lösung, die mit Lumen 5.5 mit Fremdschlüsseleinschränkungen arbeitet:

$categories = MusicCategory::all();
foreach($categories as $category)
{
$category->delete();

}
return response()->json(['error' => false]);
Alain Berrier
quelle