You might have run into a situation where your SQLModel app unexpectedly runs out of database connections. If that sounds familiar, you probably have something like this in your code:
# utils/db.py
def get_db():
"""A utility function to grab a database session."""
engine = create_engine(settings.PG_CONNECTION_STRING)
return Session(engine)
And you use it in a route like this:
# routes/some_route.py
engine = get_db()
@router.post("/search")
def query_stuff(
query_params: StuffQueryParams = Body(...),
with Session(engine) as session:
# do my query stuff here
...
):
While this works, it inadvertently creates a new session for every single call. After around 95 calls (or whatever your database's connection limit is), Postgres will start refusing new connections. Oops!
The good news is that there's a simple fix! You can adjust your code to yield a session instead of creating a new one each time:
# utils/db.py
from sqlmodel import SQLModel, Session, create_engine
from shared.config import settings
engine = create_engine(settings.PG_CONNECTION_STRING)
def get_db():
"""Yield a session instead of returning."""
with Session(engine) as session:
yield session
And in your route, modify it to reuse the session:
# routes/some_route.py
@router.post("/search")
def query_stuff(
query_params: QueryParams = Body(...),
session: Session = Depends(get_db), # <-- Reuse the session by adding the call to get_db here.
):
# do my query stuff here
...
By making these changes, you'll prevent your app from running out of database connections and ensure it can handle more requests without a hitch. Happy coding!