Nefunkční cizí klíče v nette\database

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

Ahoj,
nefunguje mi dotazování na propojené tabulky.
Mám takovýto dotaz

$this->database->table('uzivatelRole')->select('uzivatelRole.*, cisPol.*')->where('urUzivatelId', $row->uzId)->fetchPairs('cpId', 'cpKod')

a v databázi definovaný cizí klíč

alter table uzivatelRole add constraint FK_Reference_97 foreign key (urUzivatelId) references uzivatel (uzId) on delete restrict on update restrict;

ale dotaz píše chybu

No reference found for $uzivatelRole->cisPol

Kde delam chybu?

David Matějka
Moderator | 6445
+
0
-

hlasi ti to chybu s tim cisPol, jak mas definovany cizi klic tam?

konva
Člen | 88
+
0
-

ted uplne nerozumim. Odkazuju se tabulkou UzivatelRole na tabulku CisPol, tedy mam cizi klic na tabulce UzivatelRole. Proc bych mel mit nejaky cizi klic na tabulce CisPol?

Pro poradek. Na tabulce CisPol mam nastaveny cizi klic na

cisPol.cpRodicId -> cisPol.cpId

zajistujici hierarchii polozek
a klic

cisPol.cpCisId -> cis.csId

odkazujici na tabulku s definici ceselniku

David Matějka
Moderator | 6445
+
0
-

ukaz prosim celou strukturu db (respektive tech dulezitych tabulek), ja se v tech zkratkach nevyznam.. (to pouzivas nejaky nahodny generovani nazvu? :) )

konva
Člen | 88
+
0
-

Takovy paradni nazby si tvorim sam :)
Zjednodusena struktura je nasledujici. Tabulky:
cisCis – tabulka s definici ciselniku (napr. role, kategorie, zeme, …)
cisPol – polozky ciselniku
uzivatel – tabulka uzivatelů
uzivatelRole – tabulka s vazbou na uzivatele a jeho role

create table cisCis
(
   ccId                 int not null auto_increment,
   ccRodicId            int,
   ccKod                varchar(40),
   ccNazev              varchar(100),
   primary key (ccId)
);
alter table cisCis add constraint FK_Reference_1 foreign key (ccRodicId) references cisCis (ccId) on delete restrict on update restrict;

create table cisPol
(
   cpId                 int not null auto_increment,
   cpCisCisId           int,
   cpRodicId            int,
   cpKod                varchar(40),
   cpNazev              varchar(200),
   primary key (cpId)
);
alter table cisPol add constraint FK_Reference_2 foreign key (cpRodicId) references cisPol (cpId) on delete restrict on update restrict;
alter table cisPol add constraint FK_Reference_3 foreign key (cpCisCisId) references cisCis (ccId) on delete restrict on update restrict;

create table uzivatel
(
   uzId                 int not null,
   uzJmeno              varchar(200),
   primary key (uzId)
);

create table uzivatelRole
(
   urRoleId        int not null,
   urUzivatelId          int not null,
   primary key (urRoleId, urUzivatelId)
);
alter table uzivatelRole add constraint FK_Reference_16 foreign key (urRoleId) references cisPol (cpId) on delete restrict on update restrict;
alter table uzivatelRole add constraint FK_Reference_97 foreign key (urUzivatelId) references uzivatel (uzId) on delete restrict on update restrict;
David Matějka
Moderator | 6445
+
0
-

ok..
pro „to one“ smer neni dulezity nazev tabulky, ale nazev sloupce s cizim klicem, nazev cilove tabulky je dulezity pro „to many“ smer.
takze v

->select('uzivatelRole.*, cisPol.*')

nahrad cisPol za nazev sloupce (respektive jeho cast) v tabulce uzivatelRole:

->select('uzivatelRole.*, uzRole.*')
konva
Člen | 88
+
0
-

Díky, funguje to, ale úplně tomu nerozumím. Proč je tam ta hvězdička „uzRole.*“? Proč nemůžu napsat celý název sloupce?
....................
Uz chapu, ze ta chvezdicka znaci sloupce, ale moc mi nejde na rozum jaktoze mi to funguje kdyz napisu

"uzRole.*"
\-- i kdyz napicu
/--php
"uzRoleId.*"
\--
/--php
"uzRo.*"

Editoval konva (7. 2. 2014 13:41)

David Matějka
Moderator | 6445
+
+1
-

je to hlavne kvuli tomu, aby to fungovalo v activerow. budes mit activerow s uzivatelRole a budes chtit tu roli, kdybys pouzil

$uzivatelRole->uzRoleId

tak by ti to vratilo obsah sloupecku, pouzijes tedy

$uzivatelRole->uzRole

a ono to zjisti, ze neexistuje takovy sloupecek a tak to hleda, zda existuje sloupecek s FK, ktery obsahuje tento retezec

konva
Člen | 88
+
0
-

OK, díky.
Ještě bych tě využil na dvě otázky, protože s tím docela bojuju.
Navážu na ty tabulky co jsem psal výše. Mám tam ještě

mainId – tabulka, ktera slouzi k vytvareni unikagnich ID pro vetsinu obsahu
polClanek – clanky
polClanekSerial – ciselnik serialu
obsStitekSlova – ciselnik stitku (tagu)
obsStitekVazba – vazba clanku (resp ruzneho obsahu s mainId) a stitku

create table mainId
(
   miId                 int not null auto_increment,
   primary key (miId)
);

create table polClanek
(
   ckId                 int not null,
   ckUzivatelId         int,
   ckClanekKategorieId  int comment,
   ckSerialId           int,
   ckStavId             int,
   ckNadpis             varchar(200),
   primary key (ckId)
);
alter table polClanek add constraint FK_Reference_145 foreign key (ckSerialId) references polClanekSerial (srId) on delete restrict on update restrict;
alter table polClanek add constraint FK_Reference_45 foreign key (ckId) references mainId (miId) on delete restrict on update restrict;
alter table polClanek add constraint FK_Reference_51 foreign key (ckClanekKategorieId) references cisPol (cpId) on delete restrict on update restrict;
alter table polClanek add constraint FK_Reference_49 foreign key (ckStavId) references cisPol (cpId) on delete restrict on update restrict;

create table polClanekSerial
(
   srId                 int not null,
   srNazev              varchar(200),
   primary key (srId)
);

create table obsStitekSlova
(
   slId                 int not null auto_increment,
   slSlovo              varchar(100),
   primary key (slId)
);

create table obsStitekVazba
(
   svSlovoId            int not null,
   svMainId             int not null,
   primary key (svSlovoId, svMainId)
);
alter table obsStitekVazba add constraint FK_Reference_61 foreign key (svSlovoId) references obsStitekSlova (slId) on delete restrict on update restrict;
alter table obsStitekVazba add constraint FK_Reference_62 foreign key (svMainId) references mainId (miId) on delete restrict on update restrict;

A chtěl bych při výpisu článků dostat např. název seriálu, ale toto mi nefunguje

{$clanek->polClanekSerial->srNazev}

Tohle už ale jo

{$clanek->ref('polClanekSerial', 'ckSerialId')->srNazev}

Nebo nevím jak si mohu vypsat jen ty články které mají vazbu na určitý štítek (tag), je to vazba
polClanek ← obsStitekVazba → obsStitekSlova

Moc díky

vvoody
Člen | 910
+
0
-

Pred chvíľou ti to matej21 vysvetlil a ty spravíš tu istú chybu

konva
Člen | 88
+
0
-

Aha, sem vul, mi nedoslo, ze je to vlastne to stejny.
A jak udelat ten vypis clanku s urcitym stitkem? Predem se omlouvam, jestli je to opet blby dotaz.
lukas

David Matějka
Moderator | 6445
+
0
-

diky mainId tabulce je to hodne tezky, v NDBT snad nemozny…

vykasli se na tu tabulku mainId, akorat si komplikujes zivot..

konva
Člen | 88
+
0
-

No proc ne, ale tak poradte jak vyresit kdyz mam napr. tabulku „komentare“ a do ni ukladam zaznamy diskuse. Komentare jsou ale pod clanky, ale i treba pod obrazkam v galerii. A prijde mi zbytecne mit dve tabulky s komentari, jednu pro galerii a druhou pro clanky. Potrebuji mit tedy unikatni ID. A navic ty komentare musi mit cizi klic na tabulku kde jsou vsechny ID.
Rad to predelam, jen me nenapada lepsi reseni.

akadlec
Člen | 1326
+
0
-

Máš špatný návrh DB. Nemůžeš mít cizí klíč na dvě tabulky současně.

konva
Člen | 88
+
0
-

no v soucasnem navrhu nemam cizi klic na dve tabulky soucasne, proto je tam ta centralni mainId. Teda nejenom proto

Editoval konva (7. 2. 2014 14:55)

konva
Člen | 88
+
0
-

Mimochodem i kdybych tam nemel tu mainId tabulku, tak porad se snazim prijit na to jak napsat dotaz ktery by mi vratil jen clanky, ktere maji urcity tag.

Tedy zapis v SQL by vypadal takto

select * from polClanek
join obsStitekVazba on ckId=svMainId
join obsStitekSlova on svSlovoId=slId
where slSlovo='krajina'

Momentalne mam cizi klice pres tu MainId, ale nevim jak to zapsat i kdybych mel ty tabulky propojene mezi sebou.
Diky

David Matějka
Moderator | 6445
+
0
-

zkus:

$context->table('polClanek')
	->where('ckId:obsStitekVazba.svSlovo.slSlovo', 'krajina');
konva
Člen | 88
+
0
-

tak sem patral a odpoved jsem nasel tady. Je to lépe popsáno než v české dokumentaci.
A je to přesně tak jak píšeš. Super. Moc díky za pomoc a vysvětlení.