How Database Sessions Work
Exit

How Database Sessions Work

Understand the session lifecycle and how it replaces the old dict and save pattern

What changed between lessons

Before you start rewriting endpoints, notice what happened to main.py at the start of this lesson. The JSON storage code is gone:

  • save_expenses() and load_expenses() — removed
  • expenses = {} and counter = 0 — removed
  • DATA_FILE and the data_file setting — removed
  • Unused imports (json, os, pathlib) — removed

The endpoints still exist, but their bodies are all pass — placeholders waiting for database code. You will fill them in one by one across this lesson.

The session pattern

Every endpoint that reads from or writes to the database receives a session: SessionDep parameter. FastAPI calls get_session(), opens a session, and injects it before your endpoint runs.

Inside the endpoint, you work through the session:

OperationCall
Save a new recordsession.add(obj) then session.commit()
Read by primary keysession.get(Model, id)
Run a querysession.exec(statement).all()
Delete a recordsession.delete(obj) then session.commit()

Why session.refresh()

After session.commit(), the object in memory is stale — the database has updated it (for example, assigning an id), but the Python object does not know yet. Calling session.refresh(expense) pulls the current state from the database back into the object.

You need this after creating or updating a record, any time you return the object in the response.

Comparing old and new

Here is create_expense before and after, so you can see the shape of the change:

# Before — dict + counter
def create_expense(expense: Expense):
    global counter
    counter += 1
    expenses[counter] = {"id": counter, **expense.model_dump()}
    save_expenses()
    return expenses[counter]

# After — session
def create_expense(expense: Expense, session: SessionDep):
    session.add(expense)
    session.commit()
    session.refresh(expense)
    return expense

Four lines replace six. No global state, no file write, no manual ID assignment.

Next Chapter →