Database API#
- fastapi_restly.db.activate_savepoint_only_mode(make_session: async_sessionmaker[Any] | sessionmaker[Any]) None#
Intended for use in tests. Puts the session factory into savepoint-only mode so that no test data is ever committed to the database. Each test can roll back instantly by closing the session, leaving the database clean for the next test.
This is done with “create_savepoint” mode and a wrapper on engine.connect() that begins the outer transaction before the Session can use it. https://docs.sqlalchemy.org/en/20/orm/session_transaction.html#session-external-transaction
- async fastapi_restly.db.async_create_all(base_or_metadata: type[DeclarativeBase] | MetaData) None#
Async equivalent of
create_all(), on the configured async engine.Usage:
await fr.db.async_create_all(Base)
- fastapi_restly.db.configure(app: FastAPI | None = None, *, async_database_url: str | None = None, async_engine: AsyncEngine | None = None, async_make_session: async_sessionmaker[Any] | None = None, database_url: str | None = None, engine: Engine | None = None, make_session: sessionmaker[Any] | None = None, session_generator: Callable[[], AsyncIterator[AsyncSession]] | None = None, sync_session_generator: Callable[[], Iterator[Session]] | None = None, warn_on_misuse: bool | None = None, warn_on_uncommitted: bool | None = None, install_default_exception_handlers: bool = True) None#
Configure FastAPI-Restly. Call once at startup.
Pass async parameters (
async_database_url,async_engine, orasync_make_session) to enable async support, sync parameters (database_url,engine, ormake_session) for sync support, or both if your application uses both.Use
session_generator/sync_session_generator(orengine/make_session) to construct sessions your way – a custom engine, isolation level,search_path, logging, an existingsessionmaker. A custom generator’s job is to construct, yield, and clean up (close / roll back on the way out); it must not commit. Customizing how a session is built never takes the commit away from Restly.Restly owns the commit. Every write – the CRUD handlers (
handle_create/handle_update/handle_delete) andwrite_action– runsbefore_commit-> commit ->after_commitaround your domain logic; the commit is the framework’s single responsibility. A custom (non-CRUD) write route either brackets its mutation withwrite_action(...)(recommended) or commits the session itself withawait self.session.commit().By default Restly warns (
RestlyUncommittedChangesWarning) when a request finishes with uncommitted changes still in the session – the tell of a custom write route that forgot to commit. This applies to every session source, built-in or custom. A route that intentionally leaves a flush uncommitted (a validate-then-rollback dry run) should suppress the warning for just that request withsession.info["_fr_suppress_uncommitted"] = True.warn_on_uncommitted=Falseturns the check off globally; that is rarely the right response to the warning – prefer fixing the missing commit or the per-route suppression.Pass
warn_on_misuse=Trueto enable opt-in registration-time misuse warnings (RestlyMisuseWarning): when a view class is registered viainclude_view, the framework flags route-shell overrides, directsession.commit()calls in view methods, and CRUD route sets hand-rolled on a bareView. Off by default; intended for development, templates, and CI. Enable it before registering views.Pass your
FastAPIappto install fastapi-restly’s default exception handlers (currently: a translator that turns SQLAlchemyIntegrityErrorinto HTTP 409 Conflict). Setinstall_default_exception_handlers=Falseto opt out. If you do not passapphere, the handlers are registered the first time a view is mounted viafastapi_restly.include_view()instead.
- fastapi_restly.db.create_all(base_or_metadata: type[DeclarativeBase] | MetaData) None#
Create all tables for
base_or_metadataon the configured sync engine.A dev/demo convenience over
metadata.create_all(engine)so a quickstart can create its schema without reaching for the raw engine:fr.db.create_all(Base) # or fr.db.create_all(Base.metadata)
Accepts a
DeclarativeBasesubclass (its.metadatais used) or aMetaData. Requiresconfigure()first. Use Alembic migrations in production.
- fastapi_restly.db.deactivate_savepoint_only_mode(make_session: async_sessionmaker[Any] | sessionmaker[Any]) None#
Reverts the effect of activate_savepoint_only_mode. Restores the original engine.connect and disables savepoint-only mode.
- fastapi_restly.db.get_async_engine() AsyncEngine#
Return the async engine registered via configure().
- fastapi_restly.db.open_async_session() AsyncGenerator[AsyncSession]#
Open an async database session for use outside of request context.
Resolves the same source as
AsyncSessionDep: a customsession_generatorpassed tofastapi_restly.configure()if one is configured, otherwise the built-in async session factory. (The request-only uncommitted-changes check is not armed here – off-HTTP code owns its commit, exactly as a custom write route does.)Example:
async with fr.open_async_session() as session: result = await session.execute(select(User))
- fastapi_restly.db.open_session() Generator[Session]#
Open a sync database session for use outside of request context.
Resolves the same source as
SessionDep: a customsync_session_generatorpassed tofastapi_restly.configure()if one is configured, otherwise the built-in sync session factory. (The request-only uncommitted-changes check is not armed here – off-HTTP code owns its commit, exactly as a custom write route does.)Example:
with fr.open_session() as session: result = session.execute(select(User))
See also
Use Restly in an Existing Project — wiring Restly into existing engines and sessions; Deploying — production engine configuration.