Doctrine – jak na multi insert
- Phalanx
- Člen | 310
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
@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
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?
- Pavel Kravčík
- Člen | 1196
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
@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 | 59
@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
- Svaťa Šimara
- Člen | 98
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
@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 | 661
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();