Doctrine – jak na multi insert

Phalanx
Člen | 310
+
0
-

Ahoj,

chtěl bych se zeptat, jak řešíte multi insert v Doctrine? Probíhá i např. 500 dotazů do db pro jedno odeslání formuláře…

Četl jsem si o tom na stackoverflow – že to možné není (případně jen s nějakou knihovnou)
http://stackoverflow.com/…-in-one-shot

Děkuji

Svaťa Šimara
Člen | 98
+
0
-

@Phalanx Ahoj, osobně neřeším.

Zamyslel bych se ale – pokud je moje aplikace tak výkonově náročná, že musím řešit rozdíl, jestli provádím 500 insertů v transakci místo jednoho – má smysl používat tak ohromnou abstrakci, jako je Doctrine?

David Matějka
Moderator | 6445
+
0
-

Probíhá i např. 500 dotazů do db pro jedno odeslání formuláře…

to mi prijde hrozne moc. to je opravdu tak velky formular, ktery toho tolik meni/pridava?

Svaťa Šimara
Člen | 98
+
0
-

@DavidMatějka Klidně může jít o import, problém bude stejný.

Phalanx
Člen | 310
+
0
-

@DavidMatějka @SvaťaŠimara Přesně tak, může jít i o import. V mém případě jde o sadu formulářů, kde mám například 50 položek. Což se mi nezdá nijak vysoké číslo. Někde jsem to rozdělil, ale i tak…

Pavel Kravčík
Člen | 1180
+
+2
-

Také se mi to nezdá jako vysoké číslo. Skládáme dynamické tabulky na zadávání a také můžou mít 20×18 a každá buňka je entita.

Docela se nám osvědčilo udělat předfiltraci v PHP a pak terpve zapojit ORM. Tj. na začátku zpracování vytáhnout seznam aktuálních entit, porovnat se successem a udělat tři list (edit, add, remove). To pak provést či složit do transakce. Určitě nedělat foreach a ptát se na každou položku zvlášť.

Phalanx
Člen | 310
+
0
-

@PavelKravčík Díky za informaci. Zdá se mi to ovšem jako hodně náročná operace a neřeší to problém s přidáváním nových 500 položek.

Zatím jediný únik z této situace vidím v použití Nette Database pro tyto typy operací. Snažil jsem se zjistit, jak to efektivně dělají lidi co už Doctrine používají na větších projektech nebo delší čas.

ZahorskyJan
Člen | 55
+
+1
-

@Phalanx buď zpracováváme v dávkách (I v tom stackooverflow je to popsane,kdy se po nějaké větší dávce udělá flush a clear) nebo se dá z entity manageru dostat ke statementu a to už je dost nízko jako nette database a nemusí se řešit připojení přes další „knihovnu“. Navíc zachování vytváření entit přes Doctrine zachová i vyvolání eventů (prePersist apod), které mohou zajišťovat nějakou potřebnou logiku. Jedou nám tak importy produktu v tisicovkach každou hodinu a není problém

kejlicz
Člen | 201
+
0
-

Taky to dělám po dávkách 100 záznamů dám flush a clear a pořád dokola. Importuji takto XMLko a 50000 záznamů trvá asi minutu.

Svaťa Šimara
Člen | 98
+
+1
-

Autor se ptá, jakým způsobem provádět multi insert v doctrine.

Je sice cool, že ve Vašem případě používáte toto a toto. Taky že ve Vašem případě je tento přístup ok pořád neřeší autorovu otázku.

To, co tady popisujete – dávkové persistování, flushování provádí mnoho insertů v transakci. To, co autor této otázky požaduje, je jeden multi insert :-)

Phalanx
Člen | 310
+
0
-

@SvaťaŠimara Je to tak, ale rád jsem si přečetl i názory jak to provádí ostatní.

Zkoušel jsem mít podle návodu

<?php

		$arr = ['a', 'b', 'c'];
		$countries = array();

		foreach($arr as $countryName) {
			$country = new Country();
			$country->setTitle($countryName);
			$countries[] = $country;
		}

		foreach($countries as $country) {
			$this->em->persist($country);
		}

		$this->em->flush();
?>

Ale tento kód vyhodí celkem 5 dotazů (START TRANSACTION, 3 x INSERT, COMMIT).

Ještě jsem našel tento odkaz, kde to řeší, ale metoda save už není funkční
http://www.solidwebcode.com/…es-doctrine/

Uzavírám to tím, že jsem si přidal Nette Database.

Martk
Člen | 652
+
0
-

Když jsem se zabýval dávkovým zpracováním, tak jsem zkoušel i insert a vzniklo mi tohle .

Použití:

$inserts = new MultipleInsert($em->getConnection());

$inserts->addInsert('tablename', ['column' => 'value']);
$inserts->addInsert('tablename', ['column' => 'value']);
$inserts->addInsert('tablename', ['column' => 'value']);

$inserts->execute();