Performant Daten schreiben

Hallo
ich arbeite momentan an einer Schnittstelle, die aus CSV Dateien Artikeldatensätze schreiben soll. Das klappt auch soweit hervorragend.
Nur habe ich bei 600+ Artikeln irgendwann einen Memory Error:

Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 36864 bytes) in /html/shopware/vendor/doctrine/dbal/lib/Doctrine/DBAL/SQLParserUtils.php on line 275

Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 32768 bytes) in /html/shopware/vendor/symfony/error-handler/Error/OutOfMemoryError.php on line 1

kurz zum Script: im Construct wird das Repository geholt und dann eben in der Schleife daten ausgelesen und geschrieben. Gibt es eine Möglichkeit, hier die Performance im Blick zu haben und das Repository zwischendurch zu resetten?
Die Geschichte ist überhaupt nicht komplex, daher wundert es mich, dass sich das so dermaßen aufbaut.

PHP läd ja schon beim einlesen, die ganze CSV in den RAM. Und dann kommen noch die ganzen Symphony, DBAL Aktionen dazu.

Auf jeden Fall muss das Schreiben bei großen Datenmengen so funktionieren:

loop start
    update entity
    write/flush entity
loop end

und nicht so:

loop start
    update entity
loop end
write/flush entity

Hier werden nämlich alle Einträge gesammelt un am Ende in einem Rutsch aktualisiert. Das kann schonmal zu viel sein.

Generell würde ich keine großen Files mit PHP einlesen. Lieber mit Python/MySql die File in eine Datenbank laden und von da aus inkrementell mit PHP in den Shop laden. Also auch nicht alles auf einmal sondern in kleinen Schritten.

Danke für die Antwort.
ich lese nicht die ganze Datei aus, sondern Zeilenweise. Das wäre ein Ansatz.
bei SW6 gibt es doch kein Flush mehr? Der Updatebefehl ist ja direkt.

wann shopware den flush macht, weiß ich nicht. Irgendwoher müssen die Daten im RAM ja kommen.
Oder schreibst du alle Entities in eine eigene Variable (Array z.B.)?

ich halte mich da an das manual:
https://developer.shopware.com/docs/guides/plugins/plugins/framework/data-handling/writing-data

auszug: $this->productRepository->upsert([[ 'id' => '<your product ID here>', 'exampleExtension' => [ 'customString' => 'foo bar' ] ]], $context);

Für den Anfang wird es helfen die APP_ENV auf „prod“ zu ändern. Damit sparst du dir sehr viel Memory Usage.
Hintergrund ist das Shopware im „Dev“ Modus sehr viel Logging aktiv hat um die Entwicklung zu vereinfachen. In so einem Fall machts das aber schwieriger.

Mit 256mb Memory erfüllst du im übrigen nichtmal das empfohlene Setup von Shopware.

https://docs.shopware.com/de/shopware-6-de/erste-schritte/systemvoraussetzungen

1 Like

ja macht sinn. hab das memory limit hochgesetzt und die .env geändert. jetzt passt es tatsächlich