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.
-
The Hand-off: When your API route needs the database, it calls
get_db(). The code runs until it hitsyield db, then pauses right there. -
The Work: Your route uses the
dbsession to run queries, save data, etc. -
The Cleanup: Only after your route is completely finished (or if it crashes) does the code "resume" in
get_db(). -
The Finally: The execution moves to the
finallyblock, anddb.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
finallyblock 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. |

浙公网安备 33010602011771号