ZhangZhihui's Blog  

 

def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

In the above function, 'db.close()' is in the 'finally' block, so will the 'db' be closed before it is used?

 

That is a great question. It’s one of those logic puzzles that makes you do a double-take when you first see it in a FastAPI or SQLAlchemy context.

The short answer: No, the database connection will not close before it is used.

Here is the breakdown of why this pattern works and why it’s actually the "gold standard" for managing resources.


The Magic of yield

The yield keyword turns this function into a generator. Unlike a standard return (which ends the function immediately), yield pauses the function and hands the db object to whatever called it.

  1. The Hand-off: When your API route needs the database, it calls get_db(). The code runs until it hits yield db, then pauses right there.

  2. The Work: Your route uses the db session to run queries, save data, etc.

  3. The Cleanup: Only after your route is completely finished (or if it crashes) does the code "resume" in get_db().

  4. The Finally: The execution moves to the finally block, and db.close() is called.


Why the finally block is your best friend

In programming, a finally block is a "guaranteed execution" zone.

  • If everything goes right: The route finishes, and the session closes.

  • If something goes wrong: If your code throws an error or the database connection hangs, the finally block still runs.

Without this, you might end up with "leaked" connections—essentially leaving the door open and the lights on until the database eventually runs out of memory and crashes.

Summary Table

Step Action State of db
1 db = SessionLocal() Connection opened.
2 yield db Paused. Control handed to the API route.
3 Route Logic db is active and usable.
4 Route Finished Control returns to get_db().
5 finally: db.close() Connection closed safely.
posted on 2026-03-07 09:32  ZhangZhihuiAAA  阅读(19)  评论(0)    收藏  举报