2016-10-29 4 views
1

Ich versuche, meine Artikemodelle mit einer neuen Beschreibung zu aktualisieren, aber wenn der ConsoleCommand ausgeführt wird, wird nicht genügend Speicherplatz vorhanden sein. Wenn ich ein neues Artikelmodell erstelle, gibt es keine Probleme. Mein Verdacht geht dahin, dass versucht wird, alle Datensätze zu aktualisieren, anstatt auf den Punkt zu verweisen, auf den ich hingewiesen habe.Modellupdate mit Eloquent verursacht nicht genügend Arbeitsspeicher

$items = Item::query()->where('description', '=', '')->get(); 
foreach ($items as $item) { 
    if ($item->exists()) { 
     $item->description = "new description"; 
     $item->save(); 
    } 
} 

PHP Fatal error: Erlaubt Speichergröße von 134217728 Bytes erschöpft (versucht 65488 Bytes zuzuteilen) in .. \ Anbieter \ belichten \ Support \ Str.php auf der Leitung 2710

Fatal error PHP: Erlaubt Speichergröße von 134217728 Bytes erschöpft (versucht 65488 Bytes zuzuteilen) in .. \ Anbieter \ belichten \ Support \ Str.php auf Leitung 2710

count($items) = 3255 
count($item) = 1 

$items->count() = 3255 
$item->count() = 3255 

EDIT1:
Diese Frage konzentriert o Warum führt der Aufruf von $ item-> save() zu wenig Speicher? Wenn nur ein Modell gespeichert/aktualisiert werden soll.

EDIT2:
Warum sollte der folgende Code immer noch nicht genügend Arbeitsspeicher werfen?

$item = Item::where('description', '=', '')->first(); 
$item->description = "new description"; 
$item->save(); 

aber nicht, wenn die folgenden Zwecke verwendet wird anstelle von -> save():

Item::where('item_id', '=', $item->item_id)->update($item->toArray()); 
+1

Nur bei möglichen anderen Problemen sollten Sie Ihre Modellklasse "Item" einschließen –

Antwort

1

Sie sind für alle Artikel abfragt, das ist, warum Sie einen Fehler. Es ist wie das Kopieren aller Daten aus der Tabelle in den Speicher. Wenn Beschreibungen in jeder Reihe unterschiedlich sind, versuchen update() Methode zu verwenden, anstatt Zeilen nacheinander zu aktualisieren:

foreach ($data as $row) { 
    Item::where('description', 'old description') 
     ->update(['description' => 'new desccription']); 
} 

Vergessen Sie nicht description zu einem $fillable Array hinzuzufügen. Wenn Sie aus irgendeinem Grund wirklich save() anstelle von update() verwenden möchten, können Sie die Methode chunk() zum Laden von Daten verwenden.

Using the chunk method will conserve memory when working with large result sets

+0

Ohne die Speicherfunktion, beschwert sich der Konsolenbefehl nicht über den nicht ausreichenden Arbeitsspeicher. Außerdem benötige ich das Element, um die Beschreibung von woanders abzurufen, also würde ich diese Möglichkeit verlieren, wenn ich den Query Builder zum direkten Aktualisieren verwende. – user2803086

+0

@ user2803086, nun, dann füllt Ihre Abfrage eine Menge Speicher, aber nicht alle. Sie sollten den Ansatz trotzdem ändern. –

+0

Ich stimme zu, aber ich möchte nicht zu viel von der ORM-Funktionalität verlieren. Dies scheint ein seltsames Verhalten davon zu sein, warum save() möglicherweise versucht, alle $ -Elemente anstelle des bestimmten $ -Elements zu speichern, auf dem ich es anrufe. – user2803086

0

Ihre update() Funktion können mehrere Zeilen in einzelne Abfrage aktualisieren:

Item::where('description', '=', '') 
    ->update(['description' => 'new description']); 
-1

Nicht sicher, ob das hilft, aber ich hatte genau das gleiche Problem ... es, weil das Modell war, war ich "Speichern" an hatte keinen Primärschlüssel.

Verwandte Themen