Nette\Database a tabulky bez primary key (views) a Grido
- mere.gee
- Člen | 54
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)
- Milo
- Nette Core | 1283
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‘.
- mere.gee
- Člen | 54
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
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
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ě.
- sandal
- Člen | 8
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