Více databází a related – možný bug

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

Mám v configu nastaveny dvě databáze:

amcz:
	dsn: 'mysql:host=mysql;dbname=test_cz_am'
	user: test
	password: testovic
	autowired: false
	reflection: discovered
	options:
		lazy: true
pancz:
	dsn: 'mysql:host=mysql;dbname=test_cz_pap'
	user: test
	password: testovic
	autowired: false
	reflection: discovered
	options:
		lazy: true

- App\Model\Repositories\AdvertiserRepository( @nette.database.amcz.context )
- App\Model\Repositories\PAN\FeedRepository( @nette.database.pancz.context )
- App\Model\Repositories\PAN\FeedMergerRepository( @nette.database.pancz.context )

Vše funguje ok, až do doby, kdy potřebuju join na related tabulku:

$this->feedMergerRepository->findAll()->where('deleted', 0)
				->fetch()->ref('ep_feed')->url;
// Nette\Database\Reflection\MissingReferenceException
// No reference found for $ep_feed_merger->ep_feed.

Skruktura tabulek a constrainty jsou ok:

CREATE TABLE IF NOT EXISTS `ep_feed` (
	`feedid` int(10) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
	`type` enum('deal_cz','deal_sk') NOT NULL,
	`accountid` char(8) NOT NULL,
	`url` varchar(255) NOT NULL,
	`global_area` varchar(25) DEFAULT NULL,
	`create_date` datetime NOT NULL,
	`last_download_date` datetime DEFAULT NULL,
	`last_download_hash` binary(20) DEFAULT NULL,
	`last_download_status` enum('ok','download_error','parse_error') DEFAULT NULL,
	UNIQUE KEY `url` (`url`),
	KEY `accountid` (`accountid`),
	KEY `last_download_date` (`last_download_date`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `ep_feed_merger` (
	`mergerid` int(10) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
	`accountid` char(8) NOT NULL,
	`feedid` int(10) unsigned NOT NULL,
	`campaignid` char(8) NOT NULL,
	`bannerid` char(8) NOT NULL,
	`commissionid` char(8) NOT NULL,
	`deleted` tinyint(1) unsigned NOT NULL DEFAULT '0',
	UNIQUE KEY (`accountid`,`bannerid`),
	KEY `feedid` (`feedid`),
	KEY `campaignid` (`campaignid`),
	KEY `bannerid` (`bannerid`),
	KEY `commissionid` (`commissionid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

ALTER TABLE `ep_feed_merger`
	ADD FOREIGN KEY (`feedid`) REFERENCES `ep_feed` (`feedid`) ON DELETE CASCADE ON UPDATE CASCADE;

Mám za to že je chyba v dotazu, který se pou6ívá na zjištění těch FK klíčů:

SELECT CONSTRAINT_NAME, COLUMN_NAME, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME
FROM information_schema.KEY_COLUMN_USAGE
WHERE TABLE_SCHEMA = DATABASE() AND REFERENCED_TABLE_NAME IS NOT NULL AND TABLE_NAME =
'ep_feed_merger'

Používá se funkce DATABASE(), ale databáze je asi vyselectovaná ta první, tedy to nic nevrátí.

[UPDATE2] Verze Nette upgradnuta:

nette/nette: 2.3.0
nette/database: 2.3.0

Nějaký nápad jak to obejít/fixnout?

Editoval Tomáš Jacík (13. 3. 2015 21:44)

David Matějka
Moderator | 6445
+
0
-

verze nette?

Tomáš Jacík
Člen | 147
+
0
-

Já věděl že jsem něco zapomněl. Přidal jsem to do do otázky.

vvoody
Člen | 910
+
0
-

Skús len feed miesto ep_feed

Tomáš Jacík
Člen | 147
+
0
-

Hehe, tohle funguje :-)

Teď mám ale problém jinde. V té db mám abulky se třemi různými prefixy: ep_, qu_g_ a qu_pap_. U těch dalších dvou to takto jednoduše bohužel nejde.

Dá se ta detekce prefixu někde vypnout?

vvoody
Člen | 910
+
0
-

uveď kompletný príklad kde máš problém

Tomáš Jacík
Člen | 147
+
0
-

Tak jsem na to přišel, odpovím si tedy sám :-)

Musel jsem projít zdroják Nette\Database, abych pochopil, jak to vlastně celé pracuje. Jde o to, že funkce DiscoveredConventions::getBelongsToReference hledá shodu pomocí stripos v klíčích tabulky, nikoliv v tabulkách, na které ty klíče odkazují. Je tedy potřeba to použít takto:

$row = $this->feedMergerRepository->findAll()->fetch()

// Podle klíče `feedid`, který odkazuje na `ep_feed`
echo $row->ref('feed')->url;

// Podle klíče `accountid`, který odkazuje na `qu_g_accounts`
echo $row->ref('account')->name;

Ref přes accounts tedy nefungoval, protože klíč to koncové s neobsahuje.