Jak funguje funkce find() u database

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

Zdravím,
mám tabulku, která má atribut identity_id, který je v dané tabulce jak primárním tak cizím klíčem zároveň (kvůli dědičnosti tabulek). Příkaz find na takové tabulce se podle všeho nesnaží hledat primární klíč, ale atribut id, jelikož vrací hlášku Unknown column 'id' dle kterého hledá daný záznam. Opravdu takhle pracuje find? Nebo je někde jinde krpa?

Nette 2.0.6, PHP 5.3

studna
Člen | 181
+
0
-

Nejsem si jistý, ale myslím, že musíš použít Nette\Database\Reflection\ DiscoveredReflection, aby se to chovalo jak potřebuješ.

Editoval studna (25. 10. 2012 16:45)

bumprask
Člen | 59
+
0
-

a jakým způsobem se DiscoveredReflection používá? jedná se o chování příkazu ->ref(„tabulka“,„sloupec“) ?

Editoval bumprask (26. 10. 2012 10:48)

enumag
Člen | 2118
+
0
-

Pokud používáš přímo ->ref tak vůbec nezáleží jakou máš reflexi. Ta se použije jen při zápisu ->neco, kde neco není přímo sloupec, ale slouží jako ->ref na jinou tabulku. Úkol reflexe je zjistit co tím chtěl básník říci.

bumprask
Člen | 59
+
0
-

Tedy discoveredReflection je automatickou funkcí Nette Database a né funkcí, kterou jde ovládat? Moc totiž nechápu jak mám použít discoveredReflection, jak se používá a nastavuje? Na fóru tu jsou zmínky o conventialReflection a discoveredReflection, ovšem není vysvětleno jak se s tím dá pracovat.

enumag
Člen | 2118
+
0
-

V neonu nastavíš:

	nette:
		database:
			default:
				reflection: discovered
				#nebo
				reflection: conventional

Případně můžeš předat i název vlastní třídy, která implementuje potřebný interface.

Použití a rozdíly hezky popsal vvoody.

mildabre
Člen | 62
+
0
-

bumprask napsal(a):

Zdravím,
mám tabulku, která má atribut identity_id, který je v dané tabulce jak primárním tak cizím klíčem zároveň (kvůli dědičnosti tabulek). Příkaz find na takové tabulce se podle všeho nesnaží hledat primární klíč, ale atribut id, jelikož vrací hlášku Unknown column 'id' dle kterého hledá daný záznam. Opravdu takhle pracuje find? Nebo je někde jinde krpa?

Nette 2.0.6, PHP 5.3

Nějak nechápu proč Jsi použil pro primární klíč název identity_id když je to v rozporu s doporučeními autora notORM knihovny pro práci s databází (viz http://www.notorm.com/#…). Je to jednoduché pravidlo – primární klíč se vždy jmenuje id a cizí klíč odkazující do nějaké tabulky table_id. Navrhuj klíče v tabulkách vždy podle této konvence a dobře se Ti povede. Tato konvence je základem pro notORM a také pro Nette Database která je z notORM odvozena.

S tou dědičností to také zcela nechápu, zkus to více popsat o co Ti jde, nikde jsem se s tímto nesetkal.

hrach
Člen | 1834
+
0
-

not orm do toho netahejte, ma mnohem horsi discovered reflection. navic, pokud pouzivate discovered, melo by byt skoro jedno, jake konvence pouzivate.

bumprask
Člen | 59
+
0
-

Ovšem jak tedy získat data z pomocí Database z tabulky, která má dva nezávislé sloupce, které odkazují na stejnou referenční tabulku? Myslím problém ne zas tak neobvyklí, ovšem takováto struktura uvádí zřejmě Nette Database do rozpaků…

Například mějme v tabulce OSOBA tyto atributy odkazující do tabulky ADRESA

dorucovaci_addresa_id int
fakturacni_addresa_id int

Jakým dotazem získat Table\Selection, které dokáže zpřístupnit data z tabulky ADRESA pro oba atributy tabulky OSOBA?

Editoval bumprask (5. 3. 2013 20:57)

enumag
Člen | 2118
+
0
-

@bumprask: Nechápu dotaz.

foreach ($connection->table('osoba') as $osoba) {
	$osoba->dorucovaci_adresa;
	$osoba->fakturacni_adresa;
}
bumprask
Člen | 59
+
0
-

enumag napsal(a):

@bumprask: Nechápu dotaz.

foreach ($connection->table('osoba') as $osoba) {
	$osoba->dorucovaci_adresa;
	$osoba->fakturacni_adresa;
}

Jde o to, že potřebuji pracovat s třídou Nette\Database\Table\Selection, v cyklu už pracuješ s ActiveRow, pokouším se o následné:

/** @var Nette\Database\Table\Selection **/
public $data;

...

//tento select ovšem nevygeneruje očekávaný SQL dotaz a nevím jak docílit podobného selectu, aby to fungovalo
$data = $this->table("nazev_tabulky")->select("dorucovaci_adresa.mesto AS d_mesto, fakturacni_adresa.mesto AS f_mesto")

Editoval bumprask (5. 3. 2013 22:15)

enumag
Člen | 2118
+
0
-

A se Selection potřebuješ pracovat z důvodu? Většina těchto případů je chyba návrhu. ;-)

bumprask
Člen | 59
+
0
-

Například u třídy zabývající se exportem dat do CSV, které předám pouze sestavená (join) data v již hotové podobě což umožní Table\Selection. Variantu takové třídy, která by sama join-ovala data až v cyklu nad ActiveRow za pomoci ->ref() a ->related() jsem zatím neuvažoval, jelikož se mi to zdá zbytečně složité, když stačí třídě pro export předat pouze hotový select z databáze.

enumag
Člen | 2118
+
0
-

@bumprask: Ano, na tento případ to skutečně je trochu zbytečné. Imho je ale stejně tak zbytečné používat Selection, které na joiny není určené. Použij query.

bumprask
Člen | 59
+
0
-

Je to škoda, pač pokud by Database respektovalo takovýto zápis dalo by se s ním sestavit cokoliv, takto nikoliv.

A když už jsme u toho query() to se prochází a vypisuje stejně tak jako Selection? Nebo jak tedy se s jeho výsledkem pracuje?

enumag
Člen | 2118
+
0
-

@bumprask: Nette database je optimalizováno pro jiný způsob práce. Každé Selection by mělo tahat data z právě jedné tabulky, další tabulky se JOINují automaticky a POUZE v případech kdy je to potřeba pro filtrování. Samozřejmě se to dá částečně obcházet a je to ještě trochu jinak když vezmeš v úvahu agregační funkce, ale to už je na jinou diskusi. Pokoušet se jedním Selection vybrat data z více tabulek jde proti tomuto principu. Selection není nástrojem pro sestavování dotazů ala dibi fluent, přestože to tak na první pohled trochu vypadá.

Výsledek query se prochází a vypisuje stejně, ale nefungují tam ty vymoženosti ze Selection typu $book->author->name, tj. nemáš ref a related. Což v tomto případě ani nechceš, proto ti query navrhuju – přesně splňuje tvé požadavky na stavbu libovolného dotazu i tvé „nepožadavky“ na výsledný iterátor.

Editoval enumag (5. 3. 2013 23:27)

bumprask
Člen | 59
+
0
-

enumag: ok, děkuji za rady :-)

Editoval bumprask (5. 3. 2013 23:39)