📚
FastAPIとSQLModelを用いたレイヤーを跨ぐトランザクション管理
要約
上記のドキュメントを信じると単一リクエスト内部では同じ依存関係を呼び出した時にキャッシュされるため呼び出し結果はリクエストに対して一つになる
そのため、セッション取得関数を作成をして、リクエストで呼ばれる階層ごとのクラスにDIすれば以下のようなシナリオも対応可能。
class UseCase:
def __init__(self, db_session: AsyncSession = Depends(get_db_session), service: SomeService = Depends(SomeService)):
self.db_session = db_session
self.service = service
async def some_usecase(self):
try:
await self.service.do_something()
await self.db_session.commit()
catch: Exception as e:
await self.db_session.rollback()
raise e
SomeService
やSomeService
の依存関係のSomeRepository
でdb_sessionを注入しても同じセッションが使える。
class SomeRepository:
def __init__(self, db_session: AsyncSession = Depends(get_db_session)):
self.db_session = db_session
def store(self, some_entity: SomeEntity):
self.db_session.add(some_entity)
sessionの作り方
懸念
シングルトンを保証するとかではなくキャッシュの利用と書かれてるのが若干不安なのでライフサイクル管理とキャッシュ管理の実装をよく調べたほうが良いかも。
とりあえずは期待した通りに動く。
Discussion