Database
austial.database provides an async SQLAlchemy integration — a
DatabaseModule dynamic module that provisions an async engine and
session factory as injectable tokens, defaulting to a local SQLite file so
it works with zero external setup.
Setup
Simple, static connection URL:
from austial import Module
from austial.database import DatabaseModule
@Module(imports=[DatabaseModule.for_root("sqlite+aiosqlite:///./austial.db")])
class AppModule:
passConnection URL resolved at runtime from other providers (the common case —
reading it out of ConfigService):
from austial.config import ConfigService
from austial.database import DatabaseModule
@Module(
imports=[
DatabaseModule.for_root_async(
use_factory=lambda config: config.get(
"DATABASE_URL", "sqlite+aiosqlite:///./austial.db"
),
inject=[ConfigService],
),
]
)
class AppModule:
passuse_factory is called with each of inject’s tokens resolved and passed
positionally, and must return the SQLAlchemy connection URL string. The
engine itself (create_async_engine(url, **engine_kwargs)) is then built
lazily, the first time anything actually depends on it.
Injecting a session
DatabaseModule exports two string tokens instead of classes (there’s no
single “the” session/engine type to hang a type hint off of), so inject
them with Inject(...):
from austial import Inject
from austial.database import DATABASE_SESSION_FACTORY
@Injectable()
class CatsRepository:
def __init__(self, session_factory=Inject(DATABASE_SESSION_FACTORY)):
self._session_factory = session_factory
async def find_all(self):
async with self._session_factory() as session:
result = await session.execute(select(CatModel))
return result.scalars().all()DATABASE_SESSION_FACTORY resolves to an
sqlalchemy.ext.asyncio.async_sessionmaker (expire_on_commit=False);
call it to open a session, same as using SQLAlchemy directly — Austial
doesn’t wrap or hide the underlying SQLAlchemy APIs, it just wires the
engine/session-factory lifecycle into the DI container for you.
DATABASE_ENGINE is exported too, for anything that needs the raw
AsyncEngine directly (running raw SQL, managing connection-pool settings,
etc.):
from austial.database import DATABASE_ENGINESwapping in a real database
Nothing about DatabaseModule is SQLite-specific beyond the default URL —
point use_factory/for_root at any SQLAlchemy-async-compatible URL
(Postgres via asyncpg, MySQL via aiomysql, …) and everything else
(session injection, health checks) keeps working unchanged. See
Health Checks for how
DatabaseHealthIndicator uses this same session factory to verify
connectivity.