Insert vrací pouze část řádku
- Birdman
- Člen | 4
Ahoj, snažím se napsat první aplikaci v Nette, ale mám problém s vkládáním řádku do tabulky. Řádek se vloží v pořádku, ale ActiveRow, který mi vrátí funkce insert neobsahuje sloupec s primárním klíčem. V databázi se bez problému inkrementuje a uloží.
Zkusil jsem postupně následující tři možnosti, jak dostat ID vloženého záznamu a do komentářů jsem napsal, co jsem dostal:
$new = $this->getTable()->insert(array(
"Name" => $cityName,
"Country_id" => $countryId
));
echo $new->id; //Vrátí sloupec 'Country_id'
var_dump($new->toArray()); //Vypíše pouze sloupce 'Name' a 'Country_id'
echo $new->getPrimary(); //Vyhodí "InvalidStateException" se zprávou "Row does not contain primary id column data"
Ale přitom tabulku jsem vytvořil následujícím SQL skriptem, kde je jasně určeno, že ‚id‘ je primární klíč
CREATE TABLE IF NOT EXISTS city
(
id
int(11) NOT NULL AUTO_INCREMENT,
Name
varchar(40) NOT NULL,
Country_id
int(11) NOT NULL,
PRIMARY KEY (id
),
KEY fk_City_Country1_idx
(Country_id
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=4 ;
ALTER TABLE city
ADD CONSTRAINT fk_City_Country1
FOREIGN KEY
(Country_id
) REFERENCES country
(id
) ON
DELETE NO ACTION ON UPDATE NO ACTION;
Netušíte někdo prosím, co jsem mohl udělat špatně?
PHP 5.3.18
Nette Framework 2.0.8
- Šaman
- Člen | 2668
Předpokládám, že jsi zkusil vymazat cache, případně načíst stránku několikrát? Ono to s tím klíčem mi občas píše taky, ale po reloadu to běží. Nějak to souvisí s tím, že v prvním průběhu si to cachuje dotaz. Zkus to a když to nezabere, pátrej dál. (S Nette dělám už dlouho, ale kolem NDatabase pořád chodím uctivě a po špičkách, abych ji nevyplašil.)
//Edit: Jinak doporučoval bych ti nepoužívat velká písmena v databázi, ale neřeknu ti proč, jen že to nikdo nedělá :)
Editoval Šaman (6. 3. 2013 14:32)
- Birdman
- Člen | 4
getTable() je funkce, která vrací tabulku podle názvu třídy. Udělal jsem to jako v návodu na první aplikaci:
protected function getTable()
{
preg_match('#(\w+)Repository$#', get_class($this), $m);
return $this->connection->table(lcfirst($m[1]));
}
Zkusil jsem teda rovnou:
$new = $this->connection->table('city')->insert(array(
"Name" => $cityName,
"Country_id" => $countryId
));
echo $new->getPrimary();
ale stále dostávám vyjímku „Row does not contain primary id column data.“
EDIT: Zkusil jsem napevno vložit do insertu i ‚id‘ a potom to zdá se funguje. Akorát getPrimary() vrací pole, obsahující jak ‚id‘, tak i ‚Country_id‘. Je správně, že to vrací i cizí klíče? Ale řešení to není, ten autoincrement chci nechat na databázi
Editoval Birdman (6. 3. 2013 17:43)
- oldrich.valek
- Člen | 21
Mně se stává, při použití cizích klíčů (například při updatu sloupce s cizím klíčem), že stránka při prvním načtení se smazanou keší (temp) vyhodí onu vyjímku Nette\InvalidStateException: „Row does not contain primary id column data“
Update to provede, přesměruje (v mém případě na seznam kde se onen updatovaný cizí klíč používá) ale přitom to vyhodí tu výjimku. Při zaktualizování stránky se seznamem je vše OK. I při novém updatu (s nesmazanou keší) vše proběhne jak má. Je to trochu zvláštní chování.
Používám Nette\Database, Nette verze 2.0.13.