DibiDriverException #1451

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

Zdravím,
snažím sa vymazať položky v DB funkciou

	public static function deleteAllForPost($postId)
	{
		if (dibi::query('
			DELETE FROM [comments]
			WHERE [post_id] = %i', $postId
		)) return true;
		else return false;
	}

vyskočí mi ale ladenka

DibiDriverException #1451

Cannot delete or update a parent row: a foreign key constraint fails (`blog`.`comments`, CONSTRAINT `comments_ibfk_1` FOREIGN KEY (`post_id`) REFERENCES `posts` (`id`))

dá sa to nejak potlačiť? Ak som to správne pochopil, vadí, že chcem zmazať záznam podla cudzieho primárneho kľúča. Toho som si ale vedomý a vyhovuje mi to. Je to vlastne zmazanie všetkých príspevkov patriacich k danému článku.

Aký je na to správny postup?
Ďakujem

newPOPE
Člen | 648
+
0
-

Asi najrychlejsie ked zmazes „kontrolu integrity“ v DB cize zmazes relaciu ;-).

romiix.org
Člen | 343
+
0
-

Tomu celkom nechápem. Popíšem presnejšie problém.
Prešiel som tutoriál blog a snažím sa rozšíriť ho o mazanie článkov.
Ak zmažem samostatné komentáre pod článkom (po jednom podla id komentára) tak to ide v pohode. Taktiež viem zmazať jednotlivé články (po jednom podla id článka), ale iba ak k nim nie sú naviazané komentáre.
V podstate som to vyriešil, problém bol vo funkcií

	public function handleDeletePost($postId = 0)
	{
		if (PostsModel::delete($postId)) {
			CommentsModel::deleteAllForPost($postId);
			$this->flashMessage('Článok bol úspešne odstránený');
		} else
			$this->flashMessage('Článok sa nepodarilo odstrániť');
	}

proste to nedovolilo zmazať najprv články a až potom príspevky.
Riešením bolo zmazanie komentárov pred článkom.
Teraz je to v pohode, ale v zložitejších projektoch so zložitejšou viazanosťou to už bude asi problém.

Takže v podstate vyriešené.

Ale zaujímalo by ma ako sa dá zrušiť tá kontrola integrity dát. Tipujem, že to nie je extra správne riešenie ale niekedy by sa mohlo zísť aspoň vedieť ako na to.

newPOPE
Člen | 648
+
0
-

Ide o to ze, v DB (predpokladam MySQL) je nastavena relacia typu 1:N (1clanok:Nkomentov)

A pokial sa k clanku nachadzaju naviazane komentare tak sa daju nastavit akcie pre ONUPDATE a ONDELETE v databaze… resp. nastavis co sa ma udiat so zaznamami ktore su naviazane na zaznam ktory chces zmazat

v tvojom pripade by si tam na obidve mohol nastavi CASCADE co by ti tusim zabezpecilo zmazanie na strane DB a nemusis sa o to explicitne starat.

DB pre blog bola generovana pomocou Doctriny a ta ako som si vsimol pri default. nastaveniach nadefinuje v tych akciach NIC :-). DObre ze si sa pytal, budem musiet kuknut ako nastavovat taketo veci aby som to nemusel robit rucne.

romiix.org
Člen | 343
+
0
-

Hej, používam MySQL.
Vidím, že z DB mám dosť veľké medzery. O nejakom ONDELETE, ONUPDATE a CASCADE som nevedel. Budem to musieť preštudovať ako sa to používa. Vyzerá to dosť užitočne.

westrem
Člen | 398
+
0
-

Veci ako ONDELETE, ONUPDATE a CASCADE su sice pekne, ale doporucujem nepouzivat pokial clovek plne nerozumie constraintom a relaciam. Moze sa potom stat, ze „rozumnym“ nastavenim sa pri obycajnom delete zmaze polka databazy.

Preto skor odporucam proste zamenit poradie vymazavania tak ako si to spravil ty, kde mas nad tym kontrolu ;)

bojovyletoun
Člen | 667
+
0
-

Přesně tak za definici fk napsat ON DELETE CASCADE. Pokud smažeš řádek r z nějaké tabulky x, databáze zjistí, které tabulky t odkazují na tabulku x a provede příslušnou akci s řádky s těch tabulek t (možnosti jsou v případě ON DELETE:

  • CASCADE-smaže odkazující řádky tabulek t,
  • RESTRICT- zabrání (vyhodí error) smazání řádku r, dokud existuje aspoň jeden s z tabulek t,
  • NO ACTION=RESTRICT, ale bez chyby,
  • SET NULL nastaví sloupcům řádků s null,
  • SET DEFAULT)

KRomě ON DELETE existuje ON UPDATE.
wiki

Editoval bojovyletoun (20. 1. 2011 11:17)