NDB a podmínka v joinu přes dvě tabulky

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
sKopheK
Člen | 207
+
0
-

(Nette 2.1dev)

Ahoj,

výřez schématu DB: http://img.lipe.cz/notorm_join.jpg

potřeboval bych z tabulky team vytáhnout všechny záznamy, které jsou přiřazeny k nějaké fázi v tabulce phase_team (tzn. podle hodnoty id_phase). Potřebuju to z právě z tabulky team a ne třeba přes fázi. Zkoušel jsem tečky, dvojtečky a kdyby šly zadat, tak zkusím určitě i trojtečku, ale nejlepší, co dostanu, je chyba: Array to string conversion u podmínky :event_team:phase_team.id_phase = 6, jinak klasicky No reference found.

Mám tedy problém, jak v NDB zapsat následující dotaz:

SELECT *
FROM `team`
JOIN event_team ON event_team.id_team = team.id
JOIN phase_team ON event_team.id_team = phase_team.id_team
AND phase_team.id_phase =6
petr.pavel
Člen | 535
+
0
-

Řešením je nahradit druhou podmínku z JOIN/ON podmínkou ve WHERE a přehodit, do jaké tabulky se dotazuješ a které joinuješ.

Úplně nejlepší je ovšem nevytvářet takový join úplně na začátku a využít plně schopnosti NDB/NotORM dotazovat se do souvisejících tabulek, až když to je potřeba (a rychleji).

Takže odpověď na tvou otázku:

$tymy = $db->event_team()
  ->select('team.*, event_team.*, phase_team.*')
  ->where('team.phase_team:id_phase', 6)

Výsledkem je ale obrovský dataset, který nejspíš nepotřebuješ celý.

Třeba ses z jiného důvodu do phase_team už dotazoval a můžeš ho použít jako výchozí bod.
Obecně je tenhle přístup víc NotORM/Nette way, tj. dotazovat se postupně jen na to, co v té chvíli potřebuješ. Nepřipravovat si všechno předem jedním monstrdotazem.

$faze = $db->phase_team[6];
$tymy = $faze->team();

foreach ($tymy as $tym) {
  foreach ($tym->event_team() as $udalost) {

  }
}
sKopheK
Člen | 207
+
0
-

Přístup NotORM/Nette je hodně elegantní, ale měl bych pak získání stejných objektů z databáze na různých místech různě provedené a tomu se chci vyhnout. Navíc nepoužívám přímo objekty ActiveRow, ale objekty třídy, která z ní dědí, abych mohl použít určité sloupce, vztahy apod. A aby to byly objekty typu Team, musí je vytvořit třída, ze které se dotazuje na tabulku team, ta si pak pamatuje, zda se objekt už z db nevytáhl, aby se nenačítal zbytečně víckrát apod.

petr.pavel
Člen | 535
+
0
-

„Tak to bohužel,“ jak praví klasik. NDB/NotORM neumožňuje definovat vlastní podmínky pro join (ledaže by to byla nějaká nová nezdokumentovaná vychytávka DEV verze, možné je všechno).

Jedině, že by sis naprgal výjimku pro tvoje pravidlo, že instance třídy Team může vzniknout pouze dotazem do tabulky team. To bys pak mohl použít nejen řešení, která jsem ti nabídl, ale i vlastní VIEW nebo PDO::query().

sKopheK
Člen | 207
+
0
-

Nakonec to řeším tak, že přes PDO vytáhnu id týmů, které mají záznam v tabulce phase_team, a pak tyhle id předložím k načtení manažerovi. Škoda, že je NDB s těma joinama tak striktní.