Připojení více databází pres DI nette 2.3

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

Ahoj,
chtěl bych se zeptat, zda by mi mohl někdo poradit, jak připojit více databází přes neon configurátor.
Zkouším to už přibližně 5 hodin a pořád se nedaří.
Mám třídu BaseModel, ve které bych chtěl mít vytvořeno více databázových připojení.
Chtěl bych zároveň využít možnosti Nette/Database pro mysql.
V configu jsem si přidal do parameters připojení do databáze ve stejném formátu jako je například v sandboxu v sekci configu database.
Nevím jestli je to správné řešení, ale chtěl bych z třídy BaseModel být schopný zavolat funkci například na vytvoření připojení do zmíněné mysql, s tím, že bych do konstruktoru BaseModel pomocí DI vložil například service MysqlManager, který by si přečetl všechny možné připojení z configu, a pro každé připojení by vytvořil instanci třídy Context. Problém je v tom, že nevím ja použít parametry které mám v configu v parameters, tak aby se to chovalo stejně jako když mám jednu service na jednu databázi a přes DI po ní vyžaduju Context, to si to samo hezky přelouská a chápe že má array z configu database přeložit na databázové připojení.

Díky moc za odpovědi.

CZechBoY
Člen | 3608
+
0
-

Potřebuješ pracovat s více databázema najednou nebo vždy jen s jednou a jen potřebuješ nějaký DatabaseResolver, který ti řekne použij tuhle databázi (na základě nějakých externích nastaveních atd.)?

Fooly
Člen | 26
+
0
-

romiix.org: prolezl jsem snad celé forum, včetně tohoto, a bohužel nikde jsem nenašel řešení, přesto díky.
CZechBoY:
Potřeboval bych používat více databázi najednou, například kombinaci mysql, postgre, mongo.
Idea je taková, že bych měl jednu hlavní třídu, ze které bych si jen volal jednotlivé připojení.
Co se monga týče, tam to budu řešit jinak.
Pro mysql bych chtěl vytvořit nějakou továrničku, která by si z configu, níže, vzala celé pole mysql a pro každé dílčí pole by vytvořila připojení. Tuhle továrničku bych přes anotaci @inject dal právě do toho BaseModel.php A pak bych mohl pouzivat $baseModel->getMysql1()->doSomething();

<?php
parameters:
	mysql:
		db1:
			dsn:....
			user:...
		db2:
			-||-

services:
	- App\Model\ModelMysql
	- App\Model\ModelMysql(%mysql%)
?>

Problém je v tom, že když service přes DI řeknu že chci aby natáhla Context, tak to zvládne bez problému, ale když chci pro každou databázi vytvořit instanci v ModelMysql, tak nevím jak na to, protože kromě parametru connection to chce ještě další věci.
Mohl bych pro každou databázi vytvořit service zvlášt, jenže se může stát že těch připojení bude třeba 30.
Kdyby to ale byla jediná možnost, tak mě to přivádí k dalšímu problému, a to je to, že když jsem napsal do configu přímo do extension „database“ více databází, tak to vracelo chybu: Unknown configuration option database.default.db1.

<?php
database:
	db1:
		dsn: 'mysql:host=127.0.0.1;dbname=test'
		user:
		password:
		options:
			lazy: yes

services:
	- App\Model\ModelMysql(@database.db1)
?>
CZechBoY
Člen | 3608
+
0
-

Tak znova :-)
Kolik databázových spojení budeš v jednom aplikačním požadavku používat? 1 nebo více?
Na tom jakej to je databázovej server už tak nesejde…

Já používám 2 db při každým spuštění aplikace – s tím, že jeden model pracuje s jednou databází, případně má jako závislost model, co obsluhuje druhou databázi.
V config.local.neon mám asi 60 konfigurací databází (autowired: false) a vždy si vyberu databázi podle nějakých podmínek (session, databáze atd.) právě v DatabaseResolveru, z něj si pak vytáhnu instanci databáze do modelu – tzn. v BaseModel::__construct je něco jako:

/**
 * @var Nette\Database\Context
 */
protected $database; // k tomuhle pak přistupuju z potomků

public function __construct(DatabaseResolver $databaseResolver)
{
	$this->database = $databaseResolver->getCurrentDatabase();
}

a dostanu nějaký připojení (instanci třídy Nette\Database\Context protože používám tuhle vrstvu, ale jinak je to jedno).

Editoval CZechBoY (12. 9. 2016 18:15)

Fooly
Člen | 26
+
0
-

Tak to zkusím přiblížit jen na tý nejjednodušší úrovni, abych do toho nepatlal nějaký svoje nápady, který jsou pravděpodobně špatně. :)
Jde mi o to mít třídu BaseModel, která by měla funkci giveMeDatabase1();
Ta by se zeptala na config k tý databázi 1 a vrátila mi připojení typu Context.
Pak bych mohl z presenteru zavolat BaseModel a podle toho kde a jak chci jakou databázi použít bych použil danou metodu BaseModelu.

Fooly
Člen | 26
+
0
-

Takže například při odeslání nějakého formuláře v presenteru by se do tří různých databází uložily různá data.

CZechBoY
Člen | 3608
+
+1
-

V presenteru nepracuj s databází… k tomu je modelová vrstva.
Co se ti nelíbí na mým řešení (máš hned databázi v konstruktoru BaseModelu, takže se vůbec nic neliší).
Ty víš kterou databázi chceš teda používat? Nebo to záleží na nějakým stavu aplikace?