Nette\Database a tabulky bez primary key (views) a Grido

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

Ahoj, používám PHP 5.4.12 a Nette 2.0.11. V databázi mám definované view, které chci zobrazit jako tabulku pomocí datagridu. Používám Grido – super doplněk. Pokud ale vytvořím instanci Gridu a pokusím se přidat sloupec

...
$dashboard = $this->createGrid('dashboard', $this->dashboardTable);
$dashboard->addColumn('idticket', 'ID ticketu');
...
return $dashboard;

dostávám chybu LogicException: Table „dashboard_table“ does not have a primary key. Tady je screen. Zdá se, že Nette\Database\Table má problém s procházením tabulky, která nemá PK (což by nemusela).

Zvláštní je, že doplněk fungoval a fungovat přestal, když jsem pracoval na něčem jiném (css a další komponenty využívající dashboard_table – asi nulová souvislost, nefunguje i když jsem všechno zakomentoval).

Při výpisu tabulky pomocí foreach table as row mi row[‚sloupec‘] v pořádku vypíše všechno sloupce.

Zkoušel jsem všechno možné, to ani nebudu vypisovat, to byste si mysleli, že jsem blázen :) Je to pro mě opravdu důležité, díky za jakýkoli návrh nebo radu.

Editoval mere.gee (17. 7. 2013 9:21)

enumag
Člen | 2118
+
-3
-

Jaký máš důvod (výmluvu) k používání tabulky bez PK?

Milo
Nette Core | 1283
+
0
-

@enumag: Protože je to view.

Milo
Nette Core | 1283
+
+1
-

A nevím, proč tady tolik lidí prosazuje, že každá tabulka musí mít primární klíč. Záleží jen na povaze dat a typu relace. Tabulky bez PK jsou naprosto v pořádku.

JHadamcik
Člen | 47
+
0
-

Milo napsal(a):

A nevím, proč tady tolik lidí prosazuje, že každá tabulka musí mít primární klíč. Záleží jen na povaze dat a typu relace. Tabulky bez PK jsou naprosto v pořádku.

Nejsou v pořádku. To že to databázový model schroustá neznamená, že to je v pořádku.

mere.gee
Člen | 54
+
0
-

enumag napsal(a):

Jaký máš důvod (výmluvu) k používání tabulky bez PK?

Potřebuji v aplikaci jednoduše vytvořit tabulku ‚závislou‘ na mnoha tabulkách v databázi. Pokud máš nápad na lepší řešení, uvítám ho…

Milo
Nette Core | 1283
+
0
-

JHadamcik: Když mě nazajímají jednotlivé řádky tabulky, ale pouze agregované fragmenty, tak i přesto tam musím mít primární klíč? Proč?

Editoval Milo (17. 7. 2013 9:44)

Milo
Nette Core | 1283
+
0
-

mere.gee napsal(a):

enumag napsal(a):

Jaký máš důvod (výmluvu) k používání tabulky bez PK?

Potřebuji v aplikaci jednoduše vytvořit tabulku ‚závislou‘ na mnoha tabulkách v databázi. Pokud máš nápad na lepší řešení, uvítám ho…

Trochu to rozveď, hlavně co myslíš tím ‚závislou‘.

Milo
Nette Core | 1283
+
0
-

mere.gee napsal(a):

Potřebuji v aplikaci jednoduše vytvořit tabulku ‚závislou‘ na mnoha tabulkách v databázi. Pokud máš nápad na lepší řešení, uvítám ho…

Mimochodem, je dashboard_table view, jak jsem pochopil z prvního příspěvku?

enumag
Člen | 2118
+
0
-

@Milo: Ok, omlouvám se a beru zpět, špatně jsem četl a nevšiml si, že jde o view. Procházení view by NDB určitě umět měla.

mere.gee
Člen | 54
+
0
-

Milo napsal(a):

mere.gee napsal(a):

enumag napsal(a):

Jaký máš důvod (výmluvu) k používání tabulky bez PK?

Potřebuji v aplikaci jednoduše vytvořit tabulku ‚závislou‘ na mnoha tabulkách v databázi. Pokud máš nápad na lepší řešení, uvítám ho…

Trochu to rozveď, hlavně co myslíš tím ‚závislou‘.

Dobrá. Mám takovouto databázi. Tickety jsou problémy, notes jsou ‚záznamy‘ k problémům. Potřebuji zobrazit tabulku se všemi tickety (podle id), odpovídajícími zákazníky a přemdětem, agentem, stavem, prioritou apod. POSLEDNÍHO NOTE s id daného ticketu.

Editoval mere.gee (17. 7. 2013 12:11)

mere.gee
Člen | 54
+
0
-

enumag napsal(a):

@Milo: Ok, omlouvám se a beru zpět, špatně jsem četl a nevšiml si, že jde o view. Procházení view by NDB určitě umět měla.

Ona ho umí. Jak jsem psal, přes foreach mi ho normálně vypíše…

enumag
Člen | 2118
+
0
-

Nejsem si úplně jistý, ale mám pocit, že Grido je jeden z těch gridů, který vyžaduje vytáhnutí všech sloupců v jediném selectu. Je-li tomu tak, je krajně nevhodný pro Nette\Database která má úplně jinou filozofii. Lepší je použít @hrachův datagrid.

mere.gee
Člen | 54
+
0
-

enumag napsal(a):

Nejsem si úplně jistý, ale mám pocit, že Grido je jeden z těch gridů, který vyžaduje vytáhnutí všech sloupců v jediném selectu. Je-li tomu tak, je krajně nevhodný pro Nette\Database která má úplně jinou filozofii. Lepší je použít @hrachův datagrid.

Jasně, možnost vytáhnout jen některá data je fajn, ale v této aplikaci to nepotřebuji – rozhodl jsem se, že pro každou tabulku v aplikaci vytvořím odpovídající view se všemi potřebnými sloupci. Ta možnost vlastní definice datasource pomocí callbacku by mi byla stejně k ničemu…

Nejlepší by bylo najít příčinu problému, než se ho pokusíme řešit změnou datagridu nebo databáze… Jak jsem psal, zarážející je, že to fungovalo, sakra :D

Milo
Nette Core | 1283
+
+1
-

Cache jsi vymazal?

Nepřítomnost primárního klíče na tabulce bývá překážka k hodně knihovnám a nástrojům. To, jestli má tabulka sloupec s primárním klíčem určuje v Nette\Database metoda Nette\Database\IReflection::getPrimary(). Pokud používáš DiscoveredReflection, je problém ten, že PostgreSQL u view primární klíč neumí.

Řešením pro view je mít v něm sloupec s primárním klíčem nějaké „základní tabulky“, u Tebe asi idticket. A potom si podědit DiscoveredReflection:

class ViewsAndDiscoveredReflection extends DiscoveredReflection
{
	function getPrimary($table) {
		switch ($table) {
			case 'view_dashboard_table':
				return 'idticket';
		}
		return parent::getPrimary($table);
	}
}

a tuhle reflexi používat.

Ikdyž píšeš, že to dřív fungovalo, víc asi neporadím, Grido znám jen okrajově.

mere.gee
Člen | 54
+
0
-

Milo napsal(a):

Cache jsi vymazal?

Extrémně hloupý dotaz, ale myslíš cache v prohlížeči? To jo.

Editoval mere.gee (17. 7. 2013 13:10)

enumag
Člen | 2118
+
0
-

mere.gee napsal(a):

Milo napsal(a):

Cache jsi vymazal?

Extrémně hloupý dotaz, ale myslíš cache v prohlížeči? To jo.

Ne, myslel cache Nette.

mere.gee
Člen | 54
+
0
-

enumag napsal(a):

mere.gee napsal(a):

Milo napsal(a):

Cache jsi vymazal?

Extrémně hloupý dotaz, ale myslíš cache v prohlížeči? To jo.

Ne, myslel cache Nette.

A jak? $cache = new \Nette\Caching\Cache; $cache->clean();?

leninzprahy
Člen | 150
+
0
-

prostě smaž obsah adresáře temp/cache :)

enumag
Člen | 2118
+
0
-

A soubor temp/btfj.dat.

mere.gee
Člen | 54
+
0
-

Po smazání cache se tabulka jednou zobrazí, ale dočasně. Pokud jdu do view detail, kde vypisuju informace z tabulky podle id (což funguje) a vrátím se zpátky, opět to hlásí stejnou chybu :D Dokud zase nesmažu cache.

Editoval mere.gee (17. 7. 2013 14:06)

mere.gee
Člen | 54
+
0
-

Změnil jsem způsob, jakým jsem dostával data z tabulky a už to funguje :D Nechápu nic… Každopádně díky moc za pomoc!

Editoval mere.gee (17. 7. 2013 14:08)

s4muel
Člen | 92
+
0
-

@mere.gee: mam rovnaky problem, ako sa ti to podarilo vyriesit?
zobrazuje iba jedenkrat po zmazani cache.

Editoval s4muel (25. 7. 2013 9:37)

sandal
Člen | 8
+
0
-

Ahoj, já mám obecně problém s tím, že nette hlásí, že tabulka nemá primární klíč i když ho má.

Instalační skript tabulky

CREATE TABLE profile.profile
(
  id bigint NOT NULL DEFAULT nextval('profile_id_seq'::regclass),
  ...
  CONSTRAINT profile_primary_key PRIMARY KEY (id)
)
WITH (
  OIDS=FALSE
);

PHP kód

$selection = $this->connection->table('profile.profile')
                ->select('id, last_request_time', 'name')
                ->where('error = ? OR xml IS NULL',true);
foreach ($selection as $row) {
  $profileData = $this->getDataFromProfile($row['id']);
  $row->update(array('last_request_time'=> $profileData['last_request_time'], 'name'=> $profileData['name']));
}

Tenhle kód vždycky skončí chybou:

Table "profile.profile" does not have a primary key

Což je kravina, protože tabulka primární klíč má. Tušíte co změnit abych mohl updatovat? Momentálně ta aplikace jede na Nette 2.0.13