I'm developing a web app for storing and managing tasks, using Flask-SQLAlchemy to talk to the backend. I want to use a table to store priority comparisons between pairs of tasks in order to construct a partial ordering. The table will have two columns, one for the lesser element and one for the greater element, and both columns together will form the primary key.
My code so far looks like this:
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
All told, this should be sufficient for what I want to do with the table, but there's a problem in that inconsistent rows might be inserted. Suppose I have two tasks, A and B. If task A is of greater priority than task B, I could do the following:
pair = PriorityPair(task_b, task_a)
db.session.add(pair)
db.session.commit
and the relation between the two would be stored as desired. But if at some future point, the opposite relation, PriorityPair(task_a, task_b)
, were to be inserted into the table, that would be inconsistent. The two tasks can't be greater in importance than each other at the same time.
Now I could probably prevent this in python code, but I'd like to be sure that the DB table itself is guaranteed to remain consistent. Is it possible to put (via Flask-SqlAlchemy) some kind of constraint on the table, so that if (A,B)
is already present, then (B,A)
will be automatically rejected? And would such a constraint work across DB backends?