What type of Exception should SQLAlchemy model raise when an object is not found in DB?

Question:

I have a web-app that uses SQLAlchemy with the Flask framework.

Below is My SQLAlchemy model (simplified):

class MyModelA(db.Model):
    a_id = db.Column(UUIDType(binary=False), nullable=False, primary_key=True)

    @classmethod
    def get_model_a(cls, a_id):
        try:
            found_a = cls.query.get(a_id)
        except StatementError:  # when a_id is not a 16-character string
            raise SomeException
        else:
            if found_a is None:
                raise SomeException

Here is the Flask method that implements the HTTP endpoint which lets users query the database with an aID:

@app.route('/does_a_exist', methods=['post'])
def does_a_exist():
    try:
        variable_id = request.get_json().get('a_id')
        s = len(variable_id) # None object haven't any length
        MyModelA.get_model_a(variable_id)
    except SomeException:
        return jsonify(goodbye='world'), httplib.HTTP_404_NOT_FOUND
    else:
        return jsonify(hello='world'), httplib.HTTP_200_OK

When the get_model_a() fails to find the database row with the given a_id, I want it to raise an exception (SomeException) which will be caught by the does_a_exist() which will respond to the user with a 404.

My question is: Which Exception class is most suitable to be used in place of SomeException?? Can someone recommend one? I’m a SQLAlchemy newbie but I know Django well. In Django I would have raised an ObjectDoesNotExist Exception. What is the corresponding SQLAlchemy exception I should use here?

Asked By: Saqib Ali

||

Answers:

If you do not want to create your own exception class for this error, the sqlalchemy.orm.exc.NoResultFound should suit your purposes.

The docs describe the exception as:

A database result was required but none was found.

https://docs.sqlalchemy.org/en/latest/core/exceptions.html#sqlalchemy.exc.NoResultFound


SQLAlchemy already has this feature built in with the .one() method where it either returns exactly one result or raises an sqlalchemy.orm.exc.NoResultFound exception.
https://docs.sqlalchemy.org/en/14/orm/query.html#sqlalchemy.orm.Query.one

Answered By: danielx