Nefunguje mi provázání některých tabulek

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

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)

tomaass
Člen | 74
+
0
-

nejdou mi vazby ani z jiné tabulky na jinou, i když má nastavený FK. Je vůbec postgres podporován? Já začínám mít pochybnosti skoro o všem. Neví někdo, kde by mohl být problém?

vvoody
Člen | 910
+
0
-

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
+
0
-

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
+
0
-

tomaass napsal(a):

Ale ani přes ref() mi to nefunguje.

Predveď

tomaass
Člen | 74
+
0
-
	return $this->connection->table('package')->fetch()->ref('movement');
PDOException

No reference found for $package->movement.
vvoody
Člen | 910
+
0
-

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
+
0
-

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.

vvoody
Člen | 910
+
0
-

Keď postuješ nejakú chybovú hlášku tak prosím aj s kódom a vyznačeným riadok na ktorom to vybehlo. Za tou šipkou v tom errore niečo chýba. Neviem či si to len omylom neskopíroval alebo si niekde v kóde predával prázdny string.

tomaass
Člen | 74
+
0
-

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áš.

vvoody
Člen | 910
+
0
-

Myslel som aby si pastol tvoj kód, nie frameworku :D. Aha ten dvojitý PK, čo to robí ak voláš realted s obomi parametrami?

return $this->connection->table('package')->fetch()->related('movement','package_id');
tomaass
Člen | 74
+
0
-

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

vvoody
Člen | 910
+
0
-

Teraz som si všimol že aj samotný FK je dvojstĺpcový. V živote som to nevidel a nepríde mi to ako veľmi šťastný návrh databáze. Obávam sa že si ten dotaz budeš musieť napísať. Nepredpokladám že pre takéto niečo je podpora v rámci ref/related v Nette DB.

tomaass
Člen | 74
+
0
-

máte pravdu, taky jsem to neviděl a nepříjde mi to jako šťastné, ale není to moje dílo ale musím ho použít. Děkuju