Po aktualizaci nette nefunguje práce s druhou databází
- n.u.r.v.
- Člen | 485
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
nevytvarej context, rovnou si ho vyzadej:
@database.project_data.context
a to same pro druhou db
- David Matějka
- Moderator | 6445
@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
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
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
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..