I'm using flask-sqlalchemy and trying to validate input to my database. For single fields, the validate decorator works well. However, I'm having issues with preventing values from being added to a collection/relationship based the value of on another field. For example, consider the following data model:
class MyRelation(db.Model):
__tablename__ = "my_relation"
id = db.Column(db.Integer, primary_key=True)
my_data_id = db.Column(db.Integer, db.ForeignKey("my_data.id"))
some_value = db.Column(db.String)
class MyData(db.Model):
__tablename__ = "my_data"
id = db.Column(db.Integer, primary_key=True)
some_relation = db.relationship("MyRelation", backref="my_data")
some_other_value = db.Column(db.Boolean)
The problem I'm running into is I want to ensure some_relation is empty if some_other_value == True. I have looked into the following options. I'm not sure if any of these could be tuned to provide the intended functionality:
- Use
@validateswith multiple fields as specified here. The problem with this approach is it seems to validate the collection one by one, and returning None in validation for poorly formed input yieldssqlalchemy.orm.exc.FlushError: Can't flush None value found in collection Job.alternate_attributes. Returning an empty list also doesn't work. - Use a
before_insertevent listener, as outlined here. The challenge I see with this is this seems like this would not be compatible with relationship events per the official docs. - Use a
before_flushevent listener, which sounds like it might be compatible with this use case, but I'll be honest I'm having a hard time finding a good example of exactly how to use this given my goal. It's pretty abstract, and I don't see any examples in the docs (both of the examples mentioned at the end of the before_flush section don't actually contain any reference to thebefore_flushmethod they're supposedly demonstrating).
Any guidance would be much appreciated - thanks!