formatting
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
# Async SQLAlchemy Engine
|
||||
|
||||
Source:
|
||||
- https://docs.sqlalchemy.org/en/21/core/connections.html
|
||||
- https://docs.sqlalchemy.org/en/21/orm/extensions/asyncio.html
|
||||
- https://docs.sqlalchemy.org/en/21/core/pooling.html#pooling-multiprocessing
|
||||
- https://fastapi.tiangolo.com/advanced/events/
|
||||
!!! info "Primary sources"
|
||||
- [SQLAlchemy connections](https://docs.sqlalchemy.org/en/21/core/connections.html)
|
||||
- [SQLAlchemy asyncio extension](https://docs.sqlalchemy.org/en/21/orm/extensions/asyncio.html)
|
||||
- [SQLAlchemy pooling and multiprocessing](https://docs.sqlalchemy.org/en/21/core/pooling.html#pooling-multiprocessing)
|
||||
- [FastAPI lifespan events](https://fastapi.tiangolo.com/advanced/events/)
|
||||
|
||||
---
|
||||
|
||||
@@ -16,9 +16,9 @@ Create one async engine per process per database URL and keep it for the app lif
|
||||
- In FastAPI, app startup and shutdown ownership belongs in lifespan.
|
||||
- Use `FastAPI(lifespan=...)` (not startup/shutdown events) for modern lifecycle wiring.
|
||||
|
||||
Practical rule:
|
||||
- Exactly one `create_async_engine(...)` call in app bootstrap code.
|
||||
- Zero `create_async_engine(...)` calls in request handlers.
|
||||
!!! tip "Practical rule"
|
||||
- Exactly one `create_async_engine(...)` call in app bootstrap code.
|
||||
- Zero `create_async_engine(...)` calls in request handlers.
|
||||
|
||||
---
|
||||
|
||||
@@ -69,9 +69,9 @@ Use SQLAlchemy async driver URLs:
|
||||
- PostgreSQL: `postgresql+asyncpg://user:pass@host:5432/dbname`
|
||||
- SQLite: `sqlite+aiosqlite:///./app.db`
|
||||
|
||||
Notes:
|
||||
- Do not mix sync drivers (for example `psycopg2`) with `create_async_engine()`.
|
||||
- Keep URL construction centralized in settings/config, not in feature modules.
|
||||
!!! warning "Driver compatibility"
|
||||
- Do not mix sync drivers, for example `psycopg2`, with `create_async_engine()`.
|
||||
- Keep URL construction centralized in settings/config, not in feature modules.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
# Preventing Implicit ORM I/O (Asyncio)
|
||||
|
||||
Source:
|
||||
- https://docs.sqlalchemy.org/en/21/orm/extensions/asyncio.html#preventing-implicit-io-when-using-asyncsession
|
||||
- https://docs.sqlalchemy.org/en/21/orm/queryguide/relationships.html
|
||||
!!! info "Primary sources"
|
||||
- [Preventing implicit I/O with AsyncSession](https://docs.sqlalchemy.org/en/21/orm/extensions/asyncio.html#preventing-implicit-io-when-using-asyncsession)
|
||||
- [SQLAlchemy relationship loading](https://docs.sqlalchemy.org/en/21/orm/queryguide/relationships.html)
|
||||
|
||||
Status: adopted
|
||||
Decision level: advisory
|
||||
Applies to: api-runtime, workers, tests
|
||||
Last reviewed: 2026-06-17
|
||||
??? abstract "Decision metadata"
|
||||
- Status: adopted
|
||||
- Decision level: advisory
|
||||
- Applies to: api-runtime, workers, tests
|
||||
- Last reviewed: 2026-06-17
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
# DB Observability and Resilience
|
||||
|
||||
Source:
|
||||
- https://docs.sqlalchemy.org/en/21/core/pooling.html
|
||||
- https://docs.sqlalchemy.org/en/21/core/engines.html
|
||||
- https://docs.sqlalchemy.org/en/21/core/events.html
|
||||
- https://fastapi.tiangolo.com/advanced/events/
|
||||
!!! info "Primary sources"
|
||||
- [SQLAlchemy pooling](https://docs.sqlalchemy.org/en/21/core/pooling.html)
|
||||
- [SQLAlchemy engine configuration](https://docs.sqlalchemy.org/en/21/core/engines.html)
|
||||
- [SQLAlchemy events](https://docs.sqlalchemy.org/en/21/core/events.html)
|
||||
- [FastAPI lifespan events](https://fastapi.tiangolo.com/advanced/events/)
|
||||
|
||||
Status: adopted
|
||||
Decision level: mandatory
|
||||
Applies to: api-runtime, workers, tests
|
||||
Last reviewed: 2026-06-17
|
||||
??? abstract "Decision metadata"
|
||||
- Status: adopted
|
||||
- Decision level: mandatory
|
||||
- Applies to: api-runtime, workers, tests
|
||||
- Last reviewed: 2026-06-17
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
# Async SQLAlchemy Session Management
|
||||
|
||||
Source:
|
||||
- https://docs.sqlalchemy.org/en/21/orm/extensions/asyncio.html
|
||||
- https://docs.sqlalchemy.org/en/21/orm/session_basics.html
|
||||
- https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-with-yield/
|
||||
!!! info "Primary sources"
|
||||
- [SQLAlchemy asyncio extension](https://docs.sqlalchemy.org/en/21/orm/extensions/asyncio.html)
|
||||
- [SQLAlchemy session basics](https://docs.sqlalchemy.org/en/21/orm/session_basics.html)
|
||||
- [FastAPI dependencies with yield](https://fastapi.tiangolo.com/tutorial/dependencies/dependencies-with-yield/)
|
||||
|
||||
Status: adopted
|
||||
Decision level: mandatory
|
||||
Applies to: api-runtime, workers, tests
|
||||
Last reviewed: 2026-06-17
|
||||
??? abstract "Decision metadata"
|
||||
- Status: adopted
|
||||
- Decision level: mandatory
|
||||
- Applies to: api-runtime, workers, tests
|
||||
- Last reviewed: 2026-06-17
|
||||
|
||||
---
|
||||
|
||||
@@ -49,14 +50,14 @@ from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
|
||||
|
||||
|
||||
def get_session_factory(request: Request) -> async_sessionmaker[AsyncSession]:
|
||||
return request.app.state.session_factory
|
||||
return request.app.state.session_factory
|
||||
|
||||
|
||||
async def get_db_session(
|
||||
session_factory: async_sessionmaker[AsyncSession] = Depends(get_session_factory),
|
||||
session_factory: async_sessionmaker[AsyncSession] = Depends(get_session_factory),
|
||||
) -> AsyncIterator[AsyncSession]:
|
||||
async with session_factory() as session:
|
||||
yield session
|
||||
async with session_factory() as session:
|
||||
yield session
|
||||
```
|
||||
|
||||
Route usage:
|
||||
@@ -70,10 +71,10 @@ router = APIRouter()
|
||||
|
||||
@router.post("/items")
|
||||
async def create_item(session: AsyncSession = Depends(get_db_session)) -> dict:
|
||||
async with session.begin():
|
||||
# write operations here
|
||||
...
|
||||
return {"status": "ok"}
|
||||
async with session.begin():
|
||||
# write operations here
|
||||
...
|
||||
return {"status": "ok"}
|
||||
```
|
||||
|
||||
---
|
||||
@@ -86,9 +87,9 @@ Typical session factory setup:
|
||||
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
|
||||
|
||||
session_factory = async_sessionmaker(
|
||||
engine,
|
||||
class_=AsyncSession,
|
||||
expire_on_commit=False,
|
||||
engine,
|
||||
class_=AsyncSession,
|
||||
expire_on_commit=False,
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
# <Concept Title>
|
||||
|
||||
Source:
|
||||
- <primary source url>
|
||||
- <secondary source url>
|
||||
!!! info "Primary sources"
|
||||
- Primary source: `<primary source URL>`
|
||||
- Secondary source: `<secondary source URL>`
|
||||
|
||||
Status: draft|adopted|deprecated
|
||||
Decision level: advisory|mandatory
|
||||
Applies to: api-runtime|workers|tests
|
||||
Last reviewed: YYYY-MM-DD
|
||||
??? abstract "Decision metadata"
|
||||
- Status: draft|adopted|deprecated
|
||||
- Decision level: advisory|mandatory
|
||||
- Applies to: api-runtime|workers|tests
|
||||
- Last reviewed: YYYY-MM-DD
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
# Async Transaction Boundaries
|
||||
|
||||
Source:
|
||||
- https://docs.sqlalchemy.org/en/21/orm/session_transaction.html
|
||||
- https://docs.sqlalchemy.org/en/21/orm/extensions/asyncio.html
|
||||
- https://docs.sqlalchemy.org/en/21/core/connections.html
|
||||
!!! info "Primary sources"
|
||||
- [SQLAlchemy transactions](https://docs.sqlalchemy.org/en/21/orm/session_transaction.html)
|
||||
- [SQLAlchemy asyncio extension](https://docs.sqlalchemy.org/en/21/orm/extensions/asyncio.html)
|
||||
- [SQLAlchemy connections](https://docs.sqlalchemy.org/en/21/core/connections.html)
|
||||
|
||||
Status: adopted
|
||||
Decision level: mandatory
|
||||
Applies to: api-runtime, workers, tests
|
||||
Last reviewed: 2026-06-17
|
||||
??? abstract "Decision metadata"
|
||||
- Status: adopted
|
||||
- Decision level: mandatory
|
||||
- Applies to: api-runtime, workers, tests
|
||||
- Last reviewed: 2026-06-17
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user