Nefunguje mi provázání některých tabulek
- tomaass
- Člen | 74
Ahoj,
už dlouho se tady s tim peru. Používám Postgres a mám několik tabulek. Některé mají primární klíč přes více sloupců a některé mají více cizích klíčů.
Tak tedy:
tabulka ‚package‘ má primární klíč přes dva sloupce (id, component_id). Pak je tu tabulka ‚movement‘, ve které jsou pohyby balíčků (package)
Chci vypsat u jednoho balíčku nějaký jeho pohyb (po firmě). Jdu na to takto:
$this->connection->table('package')->fetch()->movement->id;
... nebo ...
$this->connection->table('package')->fetch()->ref('movement')->id;
Výsledek:
PDOException
No reference found for $package->movement.
Nebo chci vypsat primární klíč tabulky ‚package‘
return $this->connection->table('package')->getPrimary();
Výsledek:
NULL
Já vůbec nevím, jak ty tabulky elegantně spojit. Samozřejmě chci využít výhod nette database, a né tam šmudlit sql, kde bude několik spojení pomocí where…
Věděl by někdo, kde je chyba? Díky
Editoval tomaass (27. 10. 2012 12:10)
- vvoody
- Člen | 910
Primárny kľúč cez viac ako jeden stĺpec nieje podporovaný (alebo donedávna nebol, niečo sa okolo toho riešilo) preto vracia null. Neuvádzaš štruktúru tabuliek, ani použitú reflection takže ťažko pomôcť. Ak netušíš ako jednotlivé reflection fungujú tak radšej používaj metódy ref a related tak že uvedieš oba parametre.
- tomaass
- Člen | 74
Stáhnul jsem z gitu verzi, která už má PK přes více sloupců umožňovat.
Co je to reflection nevím. Ale ani přes ref() mi to nefunguje.
Strultura tabulek je následující
CREATE TABLE "package"
(
component_id integer NOT NULL,
id integer NOT NULL,
packagequantity integer NOT NULL,
quantity integer NOT NULL,
checkdate timestamp without time zone,
location_id integer,
status_id integer,
note text,
company_id integer,
supliercode text,
price real,
CONSTRAINT "PK_package" PRIMARY KEY (id, component_id),
CONSTRAINT "FK_company_id" FOREIGN KEY (company_id)
REFERENCES company (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "FK_component_id" FOREIGN KEY (component_id)
REFERENCES component (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "FK_location_id" FOREIGN KEY (location_id)
REFERENCES location (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "FK_status_id" FOREIGN KEY (status_id)
REFERENCES status (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
CREATE TABLE movement
(
id serial NOT NULL,
package_id integer NOT NULL,
component_id integer NOT NULL,
date timestamp without time zone NOT NULL DEFAULT now(),
quantity real NOT NULL,
shipment_id integer,
user_id integer NOT NULL,
action_id integer,
location_id integer,
CONSTRAINT "PK_movement" PRIMARY KEY (id),
CONSTRAINT "FK_action_id" FOREIGN KEY (action_id)
REFERENCES action (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "FK_location_id" FOREIGN KEY (location_id)
REFERENCES location (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "FK_package_id" FOREIGN KEY (package_id, component_id)
REFERENCES "package" (id, component_id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "FK_shipment_id" FOREIGN KEY (shipment_id)
REFERENCES shipment (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "FK_user_id" FOREIGN KEY (user_id)
REFERENCES "user" (id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT "UQ_movement_id" UNIQUE (id)
)
Tu databázi jsem nedělal já. Já tomu ani moc nerozumím… ale nejsou tam složitosti a podle mě by to fungovat mělo…
- vvoody
- Člen | 910
Ak netušíš ako jednotlivé reflection fungujú tak radšej používaj metódy ref a related tak že uvedieš oba parametre.
Pozri do api. Ale to bude aj tak k ničomu v tvojom prípade. Zrejme nechápeš rozdiel medzi metódami ref a related. Package má na tabuľku movement väzbu 1:N takže treba použiť metódu realted ktotá ti vráti selection. Inými slovami na jeden riadok package je naviazaných niekolko riadkov movement. Metódu ref by si použil nad riadkom z tabulky movemet aby si získal napríklad package ku ktorému patrí.
Takže zrejme potrebuješ toto:
return $this->connection->table('package')->fetch()->related('movement'/*,'package_id'*/);
// druhy parameter uviesť nemusíš, discovered reflection by ten FK mal nájsť
Alebo podľa toho čo si písal
Chci vypsat u jednoho balíčku nějaký jeho pohyb (po firmě).
jeden movement (prvý ktorý v tabuľke najde) získaš takto
return $this->connection->table('package')->fetch()->related('movement')->fetch();
- tomaass
- Člen | 74
Moc děkuji za informace. Nikde jsem to takhle přehledně nenašel.
Bohužel to ale stejně nefunguje:
PDOException
No reference found for $package->
A já vím, že tam takový záznam je. Protože když si nechám normálně fetchnout jen nalezený záznam z package, (ten co příjde první), tak podle PK (id, component_id) dohledám existující záznam v movement.
- tomaass
- Člen | 74
Bohužel, ač to tak vypadá, tak nic tam nechybí. Tedy mělo by,ale ne.
PDOException
No reference found for $package->. search►
Source file ▼
File: ...\libs\Nette\Database\Reflection\DiscoveredReflection.php:159
149: if (stripos($column, $key) !== FALSE) {
150: return array(
151: $targetTable,
152: $column,
153: );
154: }
155: }
156: }
157:
158: if (!$refresh) {
159: TADY ---> throw new \PDOException("No reference found for \${$table}->{$key}.");
160: }
161:
162: $this->reloadForeignKeys($table);
163: return $this->getBelongsToReference($table, $key, FALSE);
Mam takový dojem, že chyba bude v tom, jak jsem na začátku psal, že nad tabulkou package mi metoda getPrimary nic nevrátí. BTW: Moc ti děkuju, že mi pomáháš.
- tomaass
- Člen | 74
No v mojem kódu je pouze ona řádka. Nic jiného.
<?php
use Nette\Database\Table;
class Inventura extends \Nette\Object{
protected $connection;
public function __construct(Nette\Database\Connection $db)
{
$this->connection = $db;
}
public function pokus(){
return $this->connection->table('package')->fetch()->related('movement','component_id');
}
}
pro
return $this->connection->table('package')->fetch()->related('movement','component_id');
nebo
return $this->connection->table('package')->fetch()->related('movement','package_id');
nebo
return $this->connection->table('package')->fetch()->related('movement','id');
to hazi tu samou chybu, v te radce.
PDOException
No reference found for $package->.
stejne tak, kdyz druhy parametr predam jako pole (nevim jestli se to muze)
return $this->connection->table('package')->fetch()->related('movement',array('component_id','package_id'));
nebo
return $this->connection->table('package')->fetch()->related('movement',array('component_id','id'));
vysledkem je stejna chyba