Skip to content

Database

Async SQLAlchemy 2.x integration with asyncpg. Provides a declarative base, engine management, and a FastAPI dependency for session injection.

BluefoxBase

The shared declarative base for all SQLAlchemy models:

from sqlalchemy import String
from sqlalchemy.orm import Mapped, mapped_column
from bluefox_core import BluefoxBase

class User(BluefoxBase):
    __tablename__ = "users"

    id: Mapped[int] = mapped_column(primary_key=True)
    name: Mapped[str] = mapped_column(String(255))

get_session

FastAPI dependency that yields an AsyncSession:

from fastapi import APIRouter, Depends
from sqlalchemy.ext.asyncio import AsyncSession
from bluefox_core import get_session

router = APIRouter()

@router.get("/users")
async def list_users(session: AsyncSession = Depends(get_session)):
    result = await session.execute(select(User))
    return result.scalars().all()

If no database is configured, get_session raises HTTP 503.

DatabaseManager

Manages the async engine lifecycle. You typically don't interact with it directly — the app factory handles it.

from bluefox_core.database import DatabaseManager

manager = DatabaseManager(settings)
await manager.startup()   # verifies connectivity with SELECT 1
await manager.shutdown()   # disposes the engine

The manager is stored on app.state.db and its startup() / shutdown() methods are called automatically in the app lifespan.

URL normalization

If DATABASE_URL starts with postgresql://, it is automatically converted to postgresql+asyncpg:// for asyncpg compatibility. This means you can use the same DATABASE_URL format as tools like psql.

Running without a database

When DATABASE_URL is empty, the app starts normally — no engine is created, app.state.db.engine is None, and the /readiness endpoint skips the database check.