0

django-mptt を使用して、Web アプリのモデルにツリー構造を作成します。

残念ながら、ツリーのルート ノードが重複することがあります。

これらは、次のように、parent_id として NULL を持ち、同じ tree_id を持ちます。

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

データベースレベルでこれを止める方法はありますか?
MySQL で制約を作成して、parent_id と同じ tree_id として NULL を持つ 2 つ以上のアイテムを取得しないようにすることはできますか?

無関係なフィールドが削除された models.py のモデル:

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

1 に答える 1

0

簡単な答えはノーですが、新しい値をブロックする挿入トリガーと更新トリガーを作成できます。MySQL >= 5.5 を使用している場合は、次のようなものを使用できます -

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 ;
于 2012-03-27T20:10:27.293 に答える