An alternative way to create a check constraint is to use the event.listen event API from SQLAlchemy.
In my use case, I wanted to create a column check on my model where the column couldn't be a negative number.
event.listen(target, identifier, func)
The target in this case is my model ("Post") and my column ("upvotes"). The identifier in this case is "set". The function in this case is a static method created within my model. So it would look like this:
event.listen(Post.upvotes, "set", Post.before_set_upvotes)
My function is as follows:
@staticmethod
def before_set_upvotes(target, value, oldvalue, initiator):
if value < 0:
raise ValueError('Upvotes cannot be a negative value')
The target argument is "Post.upvotes" and value is the value we are setting the column attribute to be. NOTE: The function that is used in event.listen requires 4 arguments, I am unsure why so if someone has a reason please comment. Without 4 arguments (and just having target and value as args), I get the error TypeError: before_set_upvotes() takes 2 positional arguments but 4 were given.
Now you can test this by running a function that tried to set and commit a negative number to that column. A value error will be raised, thus creating the constraint we need.