Table ‚…‘ does not exist – jak se postavit k problému create table a následnému insertu?

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

Ahoj.

Cca před měsícem jsem si stáhnul nette 2.4. Do té doby jsem cca dva roky používal 2.2.7.
Přepsal jsem celý svůj základ webů a řeším následující problém:

Připomínám, že u Nette 2.2.7 jsem následující problém neměl.

Při instalaci projektu se provádí následující kód:

		    $this->database->query("
				CREATE TABLE IF NOT EXISTS `users` (
					`id` int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT 'primary key',
					`username` varchar(255) NOT NULL COMMENT 'unique username',
					`password` varchar(255) NOT NULL COMMENT 'password to log-in',
UNIQUE KEY `username` (`username`)
				) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='Users'");
			$user_id = $this->database->table('users')->insert([
				"username" => $installationData["username"],
				"password" => Passwords::hash($installationData["password"])
			    ])->id;

Při vkládání admin účtu insertem dojde k následující výjimce:
Table 'users' does not exist.

Když se podívám přes mysql admina, tak tabulka existuje.
Pokud provedu refresh, tak dotaz už projde, ale dostanu násleující další chybu:
Table 'resources' does not exist.
při vytváření a vkládání dat do resources tabulky a tak dále, až se nakonec všechno vloží.

Podezření mám na databázovou cache.

Jak jsem zjistil, tak:

  1. Pokud mezi create table a insert vložím
$this->database->getStructure()->rebuild();

potom je vše OK. Dojde k rebuildu cache a insert vloží do tabulky data bez chyby.

  1. Pokud před create table nedojde k SQL dotazu:

SHOW FULL TABLES
tak create a insert za sebou projdou bez problémů
Problém je, že
SHOW FULL TABLES se v mém případě zavolá pokud provedu jakýkoliv select. Tj. první create table a insert projde OK, ale další už ne.

Můj dotaz vlastně směřuje k tomu, jak bych se měl k problému postavit. Úplně nejvíc by mi vyhovovalo, kdybych se o nic nemusel starat. Prostě provedu dotazy a cache si případný rebuild zajistí sama. Jak toho ale docílit? Jde to vůbec?

No a nedělám vlastně něco úplně špatně?

Podobný problém se řešil zde:

https://forum.nette.org/cs/13163-zjisteni-existence-tabulek-v-db

Tam to autor vyřešil tak, že nejprve vytvořil tabulky a potom v dalším kroku instalace vkládal data. Tomu bych se ale rád vyhnul.

Děkuji za případné náměty :-).

Editoval ares952 (21. 12. 2016 18:20)

CZechBoY
Člen | 3608
+
0
-

Proč nemůžeš nejdřív založit tabulky a až potom do nich naházet data? Jak třeba řešíš vkládání hodnot přes cizí klíč?

ares952
Člen | 16
+
0
-

Samozřejmě, že můžu nejdřív založit tabulky a potom provést v dalším kroku inserty.
V tuhle chvíli má každý model jedinou funkci pro instalaci – tj. vytvoření tabulky a inserty. Pokud bych to rozdělil (eventuelně zkontroloval, zda mám všude CREATE TABLE IF NOT EXISTS), potom:

  1. Buď to udělat metodou next, next přes webové rozhraní
  2. Udělat to automaticky, vytvořit tabulky, provést rebuild a potom inserty

Jenže to znamená při nejmenším upravit průběh instalace. Myslel jsem si, že bude existovat nějaká obezlička, jak se tomu vyhnout.

Co máš na mysli tím vkládáním hodnot přes cizí klíč?
Při vytváření tabulky users a následném vložení získám $user_id, který potom používám při vkládání dat do další tabulky (kde je user_id FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE).

Podobně to tak dělám vždy. Zjistím cizí klíč a následně vkládám jeho referenci. Nebo jsi měl na mysli něco jiného?

edit:
To už můžu po každém creatu provést rebuild a bude to méně práce.

Editoval ares952 (21. 12. 2016 18:54)

CZechBoY
Člen | 3608
+
0
-

Po každým založení tabulky provést rebuild bude asi celkem náročný, ne?
Nicméně pokud to nechceš vše přepisovat tak asi jediná možnost.

Ještě je krajní možnost zakázat cache pro instalaci (použít třeba jiný/přídavný konfigurák) – což vyjde asi stejně jako ten rebuild.

Editoval CZechBoY (21. 12. 2016 19:46)

ares952
Člen | 16
+
0
-

Jeden rebuild trvá asi 20ms, takže to není až tak hrozný. Upravit to o rebuildy nebylo až tak hrozné.

Zajímalo by mně, jak to řeší ostatní. Přeci jsem se s tím nesetkal jako jediný? Jedná se o standardní chování?

CZechBoY
Člen | 3608
+
0
-

Ja jsem si vypl podporu Structure uplne… Ani jsem nezaznamenal zadnej rozdil krom toho ze nemusim cekat 20minut na 1 recache.

ares952
Člen | 16
+
0
-

Má v tom případě IStructure vůbec nějaký význam?

CZechBoY
Člen | 3608
+
0
-

Structure zjistuje cizi klice klice (pouzivaji se v DiscoveredReflection), typy policek (pouziva se pri pretypovani pri fetchnuti radku), primarni klic (pro joinovani a pro vraceni hodnoty PK pri insertu – opet s DiscoveredReflection).

Ja z vykonostnich duvodu pouzivam StaticReflection, nicmene se volaji i metody, ktere by se mely volat jen s DiscoveredReflection :-( tak jsem si zakomentoval pouziti Structure uplne.
Z toho vyplyva, ze mi vzdy pro kazdy sloupec prijde hodnota typu string.

ares952
Člen | 16
+
0
-

Děkuji.
uzavřeno.