📚

FastAPIとSQLModelを用いたレイヤーを跨ぐトランザクション管理

2024/07/25に公開

要約

https://fastapi.tiangolo.com/tutorial/dependencies/sub-dependencies/#using-the-same-dependency-multiple-times
上記のドキュメントを信じると単一リクエスト内部では同じ依存関係を呼び出した時にキャッシュされるため呼び出し結果はリクエストに対して一つになる

そのため、セッション取得関数を作成をして、リクエストで呼ばれる階層ごとのクラスに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

SomeServiceSomeServiceの依存関係の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の作り方

https://zenn.dev/nicopin/articles/f81a8f78b2874b

懸念

シングルトンを保証するとかではなくキャッシュの利用と書かれてるのが若干不安なのでライフサイクル管理とキャッシュ管理の実装をよく調べたほうが良いかも。

とりあえずは期待した通りに動く。

Discussion