config.ini a více databází
- xzajic
- Člen | 19
Co se mi na NETTE moc líbí je, že pomocí config.ini si můžu definovat dvě databáze. Jednu v DEVELOPMENT a druhou v PRODUCTION. Tohle funguje naprosto báječně, ve smyslu:
[development]
database.database = testovaci
[production]
database.database = ostra
Teď ale přišel zákazník s tím, že by se mu hodilo na PRODUCTION mít možnost výběru z obou DB.
Co s tím? Pokud se pokusím přepsat po přihlášení podle toho kam se
chce připojit
$prostredi = Environment::getConfig(‚database‘);
$prostredi[‚database‘]=‚testovaci‘;
Tak pochopitelně skončím na chybě „Cannot modify a frozen object ‚Config‘.“
Jinými slovy, otázka zní: Je nějaká preferovaná / oficiální cesta, jak z konfigurace nasosané z config.ini něco použít a něco redefinovat ZA BĚHU APLIKACE?
- Ondřej Mirtes
- Člen | 1536
Co to je za nesmysl? Proč by se chtěl zákazník připojovat na databázi ve tvém vývojovém prostředí? Která vůbec nemusí běžet a tudíž by neběžel ani ostrý web?
Editoval Ondřej Mirtes (11. 11. 2009 21:16)
- blacksun
- Člen | 177
Nevidím na tom nic divného, také ve firmě používáme vývojovou, testovací a ostrou db pro IS. Pravda je, že tam jsou také tři instance aplikace pro tu kterou databázi, například pro testování nějakých změn jak systému, tak nad daty, aby se nepoškodila ostrá data (disclaimer: nejedná se o webovou aplikaci).
Jak toho ale jednoduše docílit v Nette pro web, kde chci mít i testovací db pro hraní si s daty, to bych se také rád dozvěděl, i když to přímo nesouvisí s mnou popsanou situací tří db.
- Ondřej Mirtes
- Člen | 1536
blacksun napsal(a):
Nevidím na tom nic divného, také ve firmě používáme vývojovou, testovací a ostrou db pro IS. Pravda je, že tam jsou také tři instance aplikace pro tu kterou databázi, například pro testování nějakých změn jak systému, tak nad daty, aby se nepoškodila ostrá data (disclaimer: nejedná se o webovou aplikaci).
Jak toho ale jednoduše docílit v Nette pro web, kde chci mít i testovací db pro hraní si s daty, to bych se také rád dozvěděl, i když to přímo nesouvisí s mnou popsanou situací tří db.
Ano, toto skutečně je normální, A je normální k tomu mít více instancí aplikace. To znamená, že každá bude mít v configu svoji přidruženou DB.
Definování více databází v configu není problém. Ale ten požadavek od klienta xzajice zní skutečně divně.
- xzajic
- Člen | 19
Ondřej Mirtes napsal(a):
Co to je za nesmysl? Proč by se chtěl zákazník připojovat na databázi ve tvém vývojovém prostředí? Která vůbec nemusí běžet a tudíž by neběžel ani ostrý web?
Trochu se kroť ve výrazivu. Obě databáze běží na hostingu, jen jedna je s testovacími daty a druhá s ostrými. To, že tomu nerozumíš ještě neznamená, že to je nesmysl. Jinak je informační hotnota Tvého příspěvku naprosto nulová.
- xzajic
- Člen | 19
o5 napsal(a):
Jestli to nemysli autor, tak jakoze dukaz, ze na jeho „vyvojove“ databazi mu to bezi XD
Jinak to taky absolutne nechapu a jsem zvedavej na vysvetleni :)
Něco jako vnitropodnikové účetnictví kde v jedná databázi jsou data na „what if“ analýzu a ve druhé data „správná“.
- xzajic
- Člen | 19
blacksun napsal(a):
Nevidím na tom nic divného, také ve firmě používáme vývojovou, testovací a ostrou db pro IS. Pravda je, že tam jsou také tři instance aplikace pro tu kterou databázi, například pro testování nějakých změn jak systému, tak nad daty, aby se nepoškodila ostrá data (disclaimer: nejedná se o webovou aplikaci).
Jak toho ale jednoduše docílit v Nette pro web, kde chci mít i testovací db pro hraní si s daty, to bych se také rád dozvěděl, i když to přímo nesouvisí s mnou popsanou situací tří db.
Konečně mě někdo aspoň pochopil ;-) Mít kvůli tomu dvě aplikace s jediným změněným config.ini ale asi nebude to pravé. Mě by fakt stačilo, kdyby z configu nasosané informace šly „přebít“ něčím z, řekněme, přihlašovacího formuláře.
- _Martin_
- Generous Backer | 679
Napadlo mě jedno řešení, je hezké tak na půl, ale funguje dobře:
; config.ini
[common]
; databases
database.servers.s1.driver = "postgre"
database.servers.s1.host = "192.168.1.6"
database.servers.s1.user = "user"
database.servers.s1.password = "p4s5W0rD"
database.servers.s1.dbname = "database"
database.servers.s1.lazy = TRUE
database.servers.s2.driver = "mysqli"
database.servers.s2.host = "192.168.1.84"
database.servers.s2.user = "root"
database.servers.s2.password = "123"
database.servers.s2.database = "database"
database.servers.s2.lazy = TRUE
[production < common]
database.use = "s1"
[development < production]
database.use = "s2"
v místě, kde se připojuješ k DB
$database = Environment::getConfig('database');
$use = Environment::getVariable('useDb', $database['use']);
$dbConfiguration = $database['servers'][$use]; // a s tím se můžeš připojit přímo do dibi
a někde před připojením k DB
Environment::setVariable('useDb', 's1');
Protože se spojení s DB obvykle startuje dřív, než přijde na řadu nějaký kód presenterů, bylo by dobré si údaj o připojení uchovávat v session (namísto „globální“ proměnné) – to ti umožní načíst ho ještě před kódem aplikace. Tím formulářem na stránce budeš tuto hodnotu měnit (=měnit hodnotu uloženou v té session) a protože po každém zpracování akce formuláře musí dojít k přesměrování, nový požadavek bude už na zvolenou DB. Snad to pomůže=)
- xzajic
- Člen | 19
Takže, jak jsem to nakonec vyřešil:
Přece pomocí rolí! Při přihlášení uživatele mu přidělím roli (role) a podle toho si může vybrat databázi (databáze). A přihlášení k databázi jsem přesunul z bootstrapu do BasePresenteru ve smyslu:
<?php
$prostredi = Environment::getConfig('database');
$dbconfig=Array("driver"=>$prostredi['driver'], "host"=>$prostredi['host'], "username"=>$prostredi['username'], "password"=>$prostredi['password'], "database"=>$database);
dibi::connect($dbconfig);
?>