2012-03-27 3 views
0

Ich verwende django-mptt, um eine Baumstruktur in einem Modell in einer Web-App zu erstellen.Kann MySQL basierend auf einem NULL-Wert in Kombination mit einer ID einschränken?

Leider - hin und wieder bekomme ich doppelte Wurzelknoten in einem Baum.

werden diese als parent_id NULL haben, und das gleiche tree_id, wie folgt aus:

+--------+-----------+---------+ 
| id  | parent_id | tree_id | 
+--------+-----------+---------+ 
| 159092 |  NULL | 52098 | 
| 159093 |  NULL | 52098 | 
+--------+-----------+---------+ 

Gibt es eine Möglichkeit diese Ebene in der Datenbank zu stoppen?
Kann ich eine Einschränkung in MySQL machen, um zu vermeiden, dass zwei oder mehr Elemente mit NULL als parent_id und derselben tree_id erhalten werden?

Modell aus models.py mit irrelevanten Feldern entfernt:

class Message(MPTTModel): 
    # Threaded messages 
    text = textmodels.TextField() 
+0

Können Sie Ihre Datei modes.py für diese Tabelle anzeigen? – Rajeev

+0

@Rajeev - Ich habe meine Frage mit dem Minimalmodell von models.py aktualisiert. – Bohr

Antwort

0

Die einfache Antwort ist nein, aber man kann Insert und Update-Trigger erstellen, die den neuen Wert blockiert. Wenn Sie MySQL> = 5.5 verwenden, können Sie so etwas verwenden -

DELIMITER | 

DROP TRIGGER IF EXISTS before_msg_insert| 

CREATE TRIGGER before_msg_insert BEFORE INSERT ON message 
FOR EACH ROW 
BEGIN 
    DECLARE xid INT DEFAULT 0; 
    IF (NEW.parent_id IS NULL) THEN 

     SET xid = (SELECT id FROM message WHERE tree_id = NEW.tree_id AND parent_id IS NULL); 

     IF (xid > 0) THEN 
      SET @msg = CONCAT("Root node already exists. ID: ", xid); 
      SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = @msg; 
     END IF; 

    END IF; 
END| 

DROP TRIGGER IF EXISTS before_msg_update| 

CREATE TRIGGER before_msg_update BEFORE UPDATE ON message 
FOR EACH ROW 
BEGIN 
    DECLARE xid INT DEFAULT 0; 
    IF (NEW.parent_id IS NULL) THEN 

     SET xid = (SELECT id FROM message WHERE tree_id = NEW.tree_id AND id <> NEW.id AND parent_id IS NULL); 

     IF (xid > 0) THEN 
      SET @msg = CONCAT("Root node already exists. ID: ", xid); 
      SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = @msg; 
     END IF; 

    END IF; 
END| 

DELIMITER ; 
Verwandte Themen