Does an update function in the API do not raise exceptions?

Before updating, I am running a query to get the town i want to update using an id. Now my assumptions are if the id does not exist I am supposed to have an error, but I am getting none. Below is my function for update.

def update_town(session, town_dict):
    try:
        town = session.query(Town).where(Town.id == town_dict["id"] )
        print(town)
        #setting new values
        town.update(town_dict)     
        session.commit() 
    except NoResultFound:
        return "not results found", 404
    return "ok"

We can’t answer that question because we don’t know which API you are using or what it does. There are thousands of APIs in the world.

By Mwewa David via Discussions on Python.org at 13Apr2022 21:07:

Before updating, I am running a query to get the town i want to update
using an id. Now my assumptions are if the id does not exist I am
supposed to have an error, but I am getting none.

Can you post an example of town_dict for a town which does not exist,
and what you get back as town as the query result?

It is also important to say which web framekwork you’re using and which
database library. There are many choices for these :slight_smile:

That looks like an SLQAlchemy core query to me. As such, it is not
asking “which town has this id?” Instead, it is asking “which towns
have this id?” and you will always get back a list of matches.

I would neot expect a NoResultFound found exception, because it is not
a query which has to match something.

If the id does not exist that list would be empty; that is not an error.
If the id does exist, the list will have a row for every town with
that id. It is likely that the id is the primary key for your Town
relation. If so, the list will either have a length of 0 (no matches) or
1 (exactly one match).

So you need to:

Drop the try/except; as you have observed, it does not fire.

Change the query to look more like this:

towns = session.query(Town).where(Town.id == town_dict["id"] )
print(towns)
if not towns:   # like len(towns)==0, but nicer to read
    return "not results found", 404
town, = towns   # nifty assignment forcing a single match
... do stuff with the town ...
return "ok"     # not "ok", 200 ???

Cheers,
Cameron Simpson cs@cskk.id.au

Thank you so much, but what if write a query like this. am getting a different behaviour

town = session.query(Town).where(Town.id == town_dict["id"] ).one()

Thank you, i will do so next time as adviced

By Mwewa David via Discussions on Python.org at 14Apr2022 07:20:

Thank you so much, but what if write a query like this. am getting a
different behaviour
`

town = session.query(Town).where(Town.id == town_dict["id"] ).one()

Yes, because the .one() method is explicitly for situation where you
expect exactly one result, never no results or many results.

For your situation where you’re looking up a specific single town, it is
a good choice, letting you do your try/except form which is what you
originally had. You were just using a query which could return any
number of results, so the exception was not raised. With .one() you’re
explicitly using a method which should always find exactly one answer.

The docs for .one() are here:
https://docs.sqlalchemy.org/en/14/orm/query.html#sqlalchemy.orm.Query.one

There’s also .one_or_none() immediately below it on that page,
allowing:

town = session.query(Town).where(Town.id == town_dict["id"]).one_or_none()
if town is None:
    return 404, "not found"
... do stuff with town here ...

which is often more compact and readable than a try/except.

Cheers,
Cameron Simpson cs@cskk.id.au