Nette\Database: představení
- PetrNovotny
- Člen | 5
Osobně se mi moc nelíbí nazývat pilířem modelu implementaci Table a Row
Gateway jakou je Nette\Database nebo notORM a demonstrovat jí na příkladech
typu načtění dat z presenteru nebo přímo z view. Spoustu lidí to může
naučit špatnýmu přístupu k tomu jak podobný nástroje používat..
Jinak samozřejmě dobrá práce;) Ale použití bych demonstroval asi jinak,
vyloženě na načtení dat do modelu aplikace..
- Michal Blaha
- Člen | 2
Trošku se zpožděním k otázce „umí joinovat subselecty?“
vrana napsal(a):
Tak to nejde. K čemu se to hodí?
například:
SELECT * FROM car
INNER JOIN (
SELECT * FROM event WHERE type = 5
) event ON car.id = event.car_id
je rychlejší než:
SELECT * FROM car
INNER JOIN event ON car.id = event.car_id
WHERE event.type = 5
vrana napsal(a):
Tomu se mi nechce věřit…
Pokoušel jsem se to nasimulovat a musím tě dát za pravdu.
… pošlu nějaký lepší příklad, až na něj narazím :-)
Editoval Michal Blaha (30. 4. 2011 23:59)
- vrana
- Člen | 131
Michal Blaha napsal(a):
… na MySQL tabulkách obsahujících velké množství dat (statisíce řádků) jsme tím dosáhli zkrácení času až o 75%
Tomu se mi nechce věřit. Co na to říkal EXPLAIN
? Nedalo se
běžnému JOINu trochu napovědět (třeba použitím LEFT JOIN
s tabulkami v lepším pořadí nebo klauzulí USE INDEX
)? Jak je
na tom výkonnostně „nativní“ NotORM řešení?
<?php
$db->car("id", $db->event("type", 5)->select("car_id")
?>
- Peter
- Člen | 12
Jak moc je Nette\Database hotová? Tuhle David povídal cosi o tom, že to není ještě úplně ono a s případným nasazením se má ještě počkat, ale jak koukám, tak se to tu vesele používá.
Mám totiž v plánu to použít pro jeden větší projekt a nerad bych v půlce vývoje narazil na nějakou záludnou past v podobě chybějícího čehosi. Hrozí tu něco takového, nebo se případně dá zároveň s Nette\Database použít něco pod tím (PDO?) či úplně jiného (NotORM, Doctrine2)?
- Honza Marek
- Člen | 1664
Úplně hotové to rozhodně není. Rozumné je asi použít dibi, NotORM nebo Doctrine2, podle toho jaký styl práce s modelem je člověku vlastní. Jinak NotORM by měl být Nette\Database hodně podobný.
- Bernard Williams
- Člen | 207
Nazdárek,
nové databáze nepodporují dibi operátory typu %v, %a, %if, %end, %and atd? Jak se řeší dotazy s těmito operátory? Mají nějaké ekvivalenty nebo na vše stačí „?“ ?
Bernard
- Filip Procházka
- Moderator | 4668
Takové věci z principu nepotřebuješ. Použij konstrukce php
$q = $database->select...;
if ($neco) {
$q->where(...;
}
foreach ($q as $row) {
...
- Jan Voráček
- Člen | 90
Nette\Database\Connection
dědí od PDO
, takže
můžeš používat metody PDO – viz API.
Metoda insert()
pak navíc vrací ActiveRow
s vloženými daty včetně vygenerovaného id.
- David Grudl
- Nette Core | 8218
Nette\Database jako náhrada za dibi by měla být plně funkční, prakticky od vydání. Integrované NotORM (řekněme náhrada za DibiFluent) ještě není finální.
- Bernard Williams
- Člen | 207
No docela se teď s Nette\Database peru.. Pak by bylo super rozšířit dokumentaci.
Jo a ještě jedna věc. Nevím, jestli je to chyba PDO nebo Nette\Database / NotORM, ale v případě, že v SQL dotazu vybírám 2× stejnou buňku (pochopitelně omylem), tak dochází k přetypování některých buňkách (zatím jsem nenašel logiku ve kterých – asi se to řídí podle pořadí/indexů) – nehodí to žádnou chybu! Když stejný SQL dotaz dám třeba do Admineru, tak to funguje správně – tj. ve výsledku se zobrazí 2× stejná buňka se stejnou hodnotou a zbytek je takový, jak má být. String se třeba změní na „TRUE“ nebo „1“, prázdný řetězec na 0 atd.. prostě chaos.
- josef.sabl
- Člen | 153
hrach napsal(a):
Musíš použít DiscoveryReflection. Pak stačí
Co je DiscoveryReflection?
- paranoiq
- Člen | 392
DiscoveryReflection zjišťuje strukturu tabulek (cizí klíče atd.) přímo z databáze a napovídá Selection/ActiveRow, kam mají pro data sahat. je pomalejší, ale funguje nezávisle na použité konvenci. (v uvedeném příkladu konvenci dodržet nelze)
Editoval paranoiq (12. 12. 2011 18:52)
- josef.sabl
- Člen | 153
paranoiq napsal(a):
DiscoveryReflection zjišťuje strukturu tabulek (cizí klíče atd.) přímo z databáze a napovídá Selection/ActiveRow, kam mají pro data sahat. je pomalejší, ale funguje nezávisle na použité konvenci. (v uvedeném příkladu konvenci dodržet nelze)
Díky za odpověď. Samozřejmě tuším, co to znamená obecně. Mně šlo ale o vazbu a použití v Nette. Jediné, co našel Google na téma Nette DiscoveryReflection kloudného je totiž tohle vlákno.
Nakonec jsem se k tomu propídil tak, že jsem objevil funkci Connection->getDatabaseReflection(), zkusil jsem ji použít, zjistil jsem, že vyšlo nový Nette a pak v config.neon jsem objevil zmínku o reflexi.
Pracovat s Nette je radost. A teď to myslím upřímně i sarkasticky zároveň, připadám si jako zlatokop :-)
- josef.sabl
- Člen | 153
paranoiq napsal(a):
tak ses měl zeptat jak se to používá ;-]
V tom kontextu jsem myslel, že to bude jasný,
ale máš pravdu, byl jsem trochu moc stručnej ;) Díky
Editoval josef.sabl (13. 12. 2011 15:03)
- bojovyletoun
- Člen | 667
Co zvážit přidání fetchAll():https://github.com/…6f153e391eaf
Jo ještě mám jeden nápad, nebo spíš, by mě zajímalo, jaké chování
vám připadá normální (u případu 2)(1 fungujetak jak chci)
Co takhle upravit metodu update, aby entitě nastavila updatované hodnoty? Je
to žádoucí? Myslím že by stačilo něco upravit metodu update
$task=$db->table(tasks)->get(14); //1,2,...
//1.
$task1->done = !$task->done;
$task1->update();
$task1->done nyní obshahuje aktuální hodnotu.
//2.
$task2->update(array('done' => !$task->done));
$task2->done obsahuje hodnotu před updatem.
//3.
Samozřejmě pak je tu možnost místo !$task->done použít new Literal('not done');, ale tam je evidentní, by bylo nutné po updatu data hned přečíst z db.
Zmíněná úprava
Editoval bojovyletoun (28. 12. 2011 21:55)
- juzna.cz
- Člen | 248
EDIT: presunuto do vlastniho vlakna
foreach ($database->table('application')->where('authorId = ?', $authorId) as $application) { echo $application->title, ' (', $application->author->name, ')'; foreach ($application->related('application_tag') as $application_tag) { echo $application_tag->tag->name . ', '; } }
Mam prakticky stejne schema a stejny cyklus, jako bylo zmineno, ale natahuju
a vypisuju treba 1–2tis polozek z application
. Vnitrni cyklus pak
udela SQL dotaz obsahujici 1–2tis. polozek v IN
a to je strasne
pomale :(
Jak takovy pripad resite vy? Kdyby bylo k dispozici fetchAssoc()
tak si udelam join a rozparsuju si to do pole, ale takto jsem ztracen :(
Dik
Edit: Napadlo me udelat si k takove tabulce hint, pomoci ktereho by se delalo related query:
$tbl = $database->table('application')->where('authorId = ?', $authorId);
$tbl->referenceHint('application_tag', 'application.authorId = ?', $authorId); // pouzij join
Selection::getReferencingTable()
by pak pouzila tento hint,
pokud by byl dostupny. U me se to dela 10ti nasobne zrychleni (10s → 1s)
Editoval juzna.cz (6. 3. 2012 0:17)
- Dawe3081
- Člen | 2
Ahoj, s Nette začínám. Můžu se zeptat jak by se z uvedené databáze získaly všechny odpovídající záznamy z tabulky application, pokud zadám tag.name? SQL kód by vypadal asi takto:
/--application.title,application.web, application.slogan
from application, application_tag, tag
where application.id=application_tag.application_id and
tag.id = application_tag.tag_id and
tag.name = $name\--
Děkuji za odpovědi.
Editoval Dawe3081 (26. 4. 2013 16:50)
- hrach
- Člen | 1838
- http://public.skrasek.com/…a_2012_04_28
- pozor, nova backjoin syntaxe
$c->table('application')->where(':application_tag.tag.name', $mytag);