Po aktualizaci nette nefunguje práce s druhou databází

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

Ahoj, včera jsem aktualizoval nette přes composer a od té domy mám problém s prací ve druhé DB…
Když se snažím pracovat s druhou DB, spadne to a dostanu chybu Nette\InvalidArgumentException Table ‚user_change‘ does not exist
Takto to mám řešené a do aktualizace to fungovalo:

config.local.neon:

database:
	project_data:
		dsn: 'mysql:host=IP_ADRESA_1;dbname=project_data'
		user: nejaky_user
		password: 123456
	project_log:
		dsn: 'mysql:host=IP_ADRESA_1;dbname=project_log'
		user: nejaky_user
		password: 123456
	jiny_project_users:
		dsn: 'mysql:host=IP_ADRESA_2;dbname=jiny_project_users'
		user: nejaky_jiny_user
		password: 7890
		options:
			lazy: yes

config.neon:

services:
	authenticator: Authenticator
	-...
	-...
	- Model\UserRepository(Nette\Database\Context(@database.project_data), Nette\Database\Context(@database.project_log))
	-...
	-...
	- App\RouterFactory
	router: @App\RouterFactory::createRouter

Model\UserRepository.php

<?php

namespace Model;

use Nette\Database\Context;
use Nette;
use Nette\Utils\Validators;
use Nette\Utils\Strings;


class UserRepository extends Nette\Object {

    private $database_data;
    private $database_log;
    private $universalRepository;
    private $mail_template_activation;
    private $mail_template_forgot;
    private $mail_template_confirmEmail;

    public function __construct(Nette\Database\Context $database_data, Nette\Database\Context $database_log, \Model\UniversalRepository $universalRepository, \Model\ParamRepository $param) {//$mail_template_activation, $mail_template_forgot, $mail_template_confirmEmail
        $this->database_data = $database_data;
        $this->database_log = $database_log;
        $this->universalRepository = $universalRepository;
        $param = $param->getParam();
        $this->mail_template_activation = $param['mail_template_activation'];
        $this->mail_template_forgot = $param['mail_template_forgot'];
        $this->mail_template_confirmEmail = $param['mail_template_confirmEmail'];
    }

...
...
metoda, kde používám obě DB a kde to právě nefunguje:
public function forgotPasswordSend($email){
	$user = $this->getUser($email); // volani metody kde se z první db (project_data) načte info o uživateli - to funguje
...
...
...
	$insert = $this->database_log->table("user_change")->insert(array(...,...,...));
**A tady na tom insertu to spadne - neexistuje tabulka user_change**
}


}

Když se podívám do výpisu DB v tracy, tak je tam akorát prohledávání první DB (nevím proč, když chci pracovat s druhou DB) – SHOW FULL COLUMNS, …

Nouzově jsem to přepsal na ruční query(INSERT INTO project_log.user_change(sloupce) VALUES (hodnoty)). To funguje, jen nemám ošetřené vstupní stringy (jak je dočasně ošetřit, než se vyřeší hlavní problém?).

Nevíte kde může být problém?

edit: Když v vendor/nette/database/src/Database/Structure.php:249 zakomentuju throw new Nette\InvalidArgumentException(„Table ‚$name‘ does not exist.“);, tak to funguje…

Editoval n.u.r.v. (19. 10. 2015 10:11)

David Matějka
Moderator | 6445
+
+2
-

nevytvarej context, rovnou si ho vyzadej: @database.project_data.context a to same pro druhou db

n.u.r.v.
Člen | 485
+
0
-

Díky moc, na localu funguje… Jdu to předělat do všech projektů kde to používám takto asi rok…

jednou
Člen | 14
+
0
-

Ahoj, jak mam postupovat, kdyz chci predat obe instance rovnou do konstruktoru presenteru?

David Matějka
Moderator | 6445
+
+1
-

@jednou opravdu s tim potrebujes pracovat v presenteru? nebude lepsi si vytvorit nejakou sluzbu?

Ale pokud ano, tak presenter muzes registrovat jako sluzbu a ty zavislosti predat jako jine sluzbe

jednou
Člen | 14
+
0
-

ok, takze udelal jsem to rucne v konstruktoru BasePresenteru takhle:

public function __construct( Nette\Database\Context $database ) {
        $this->database = $database;
        $storage = new FileStorage("temp".DIRECTORY_SEPARATOR."druha_database");
        $connection = new Connection('mysql:host='.DBHOST.';dbname=druha_databaze', DBUSER, DBPASS);
        $reflection = new Nette\Database\Reflection\DiscoveredReflection($connection, $storage);
        $this->druha_db = new Context($connection, $reflection, $storage);
}

Vznikly mi otazky:
Proc to jde jednoduse predavat v Contextu pouze v pripade, ze DB je jen jedna?
Jake vyhody ma sluzba? (asi offtopic, že?)
Potreboval bych priklad, dosud jsem si vystacil se ctenim z DB pres tridni promennou $database.

David Matějka
Moderator | 6445
+
0
-

ok, takze udelal jsem to rucne v konstruktoru BasePresenteru takhle

proc to vyvaris rucne? a je tam nekolik problemu, od konstant, ktere pres relativni cestu k storage…

Proc to jde jednoduse predavat v Contextu pouze v pripade, ze DB je jen jedna?

protoze ty dve instance db spojeni jsou porad stejneho typu a nette nedokaze rozpoznat, kterou chces

Jake vyhody ma sluzba? (asi offtopic, že?)

zjednudusis kod v presenteru, odstinis presenter od databaze, zamezis duplikaci kodu

......

dale, do base presenteru bys nemel predavat pres kontruktor, pak se ti budou hure predavat zavislosti do jinych presenteru

a otazka nakonec: proc potrebujes dve databaze?

jednou
Člen | 14
+
0
-

Ahoj, rucne proto, protoze nevim jak jinak to dostat do vsech konstruktoru. Konstanty snad nejsou deprecated. Není to ciste nette aplikace, ale pridavam nette k necemu rozpracovanemu. Relativni cestu opravim.

Tak pokud mam dve instance db v config.neonu a dva argumenty typu context v basepresenter::__construct(a,b), tak by si je nette mohlo ocislovat, treba od 0 :)

Proc dvě? Protoze databazi nedelam ja, ta uz stoji, a je treba s ni taky pracovat.

Díky, řešení mám, třeba v dalším projektu snad pochopím význam těch služeb..