Ich entwickle eine Web-App zum Speichern und Verwalten von Aufgaben unter Verwendung von , um mit dem Backend zu sprechen. Ich möchte eine Tabelle verwenden, um Prioritätsvergleiche zwischen Aufgabenpaaren zu speichern, um eine partial ordering zu erstellen. Die Tabelle wird zwei Spalten haben, eine für das kleinere Element und eine für das größere Element, und beide Spalten bilden zusammen den Primärschlüssel.Wie kann ich bestimmte Kombinationen von Werten in einer Tabelle verhindern, die von den bereits in der Tabelle angegebenen Werten abgeleitet sind?
Mein Code so sieht weit wie folgt aus:
class PriorityPair(db.Model):
lesser_id = db.Column(db.Integer, db.ForeignKey('task.id'),
primary_key=True)
lesser = db.relationship('Task', remote_side=[id])
greater_id = db.Column(db.Integer, db.ForeignKey('task.id'),
primary_key=True)
greater = db.relationship('Task', remote_side=[id])
def __init__(self, lesser, greater):
self.lesser = lesser
self.greater = greater
Alles in allem, ist dies für ausreichend sein sollte, was ich mit dem Tisch machen wollen, aber es gibt ein Problem, dass inkonsistente Zeilen eingefügt werden könnten. Angenommen, ich habe zwei Aufgaben, A und B. Wenn Task A von mehr Priorität als Aufgabe B ist, konnte ich folgendes tun:
pair = PriorityPair(task_b, task_a)
db.session.add(pair)
db.session.commit
und die Beziehung zwischen den beiden würde gespeichert werden, wie gewünscht. Aber wenn zu einem späteren Zeitpunkt die entgegengesetzte Beziehung, PriorityPair(task_a, task_b)
, in die Tabelle eingefügt werden würde, wäre das inkonsistent. Die beiden Aufgaben können nicht gleichzeitig wichtiger sein als einander.
Jetzt könnte ich wahrscheinlich dies in Python-Code verhindern, aber ich möchte sicher sein, dass die DB-Tabelle selbst garantiert konsistent bleibt. Ist es möglich (über Flask-SqlAlchemy) eine Art Einschränkung für die Tabelle zu setzen, so dass (A,B)
bereits vorhanden ist, dann wird automatisch zurückgewiesen? Und würde solch eine Beschränkung über DB-Backends funktionieren?
Sie könnten wahrscheinlich eine [CHECK-Einschränkung] (http://docs.sqlalchemy.org/en/latest/core/constraints.html#check-constraint) erstellen, die die transitive Eigenschaft der Reihenfolge erzwingt, aber DB-übergreifend Portabilität ist begrenzt. –
@LukasGraf Können Sie das in Form einer Antwort unten setzen? – izrik
Ich habe CHECK Constraints noch nicht für irgendetwas nicht-Trivial verwendet, und mir fehlt derzeit die Zeit und das notwendige Setup, um eine halbwegs anständige Antwort zu schreiben. Aber wenn du herausfinden kannst, wie es für deinen Anwendungsfall funktioniert, werde ich es gerne tun, wenn du es als Selbstantwort postest. –