@@ -31,34 +31,34 @@ Create a test.py file and copy the following code into it
3131
3232``` python
3333from pathlib import Path
34- from typing import Any, ClassVar
34+ from typing import Any, ClassVar, Optional
3535
3636import uvicorn
3737from fastapi import APIRouter, Depends, FastAPI
3838from pydantic import ConfigDict
39- from sqlalchemy import Column, Integer, Text
4039from sqlalchemy.engine import make_url
41- from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
42- from sqlalchemy.ext.declarative import declarative_base
43- from sqlalchemy.orm import sessionmaker
40+ from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, async_sessionmaker, create_async_engine
41+ from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
4442
4543from fastapi_jsonapi import RoutersJSONAPI, init
4644from fastapi_jsonapi.misc.sqla.generics.base import DetailViewBaseGeneric, ListViewBaseGeneric
4745from fastapi_jsonapi.schema_base import BaseModel
4846from fastapi_jsonapi.views.utils import HTTPMethod, HTTPMethodConfig
4947from fastapi_jsonapi.views.view_base import ViewBase
5048
51- CURRENT_FILE = Path(__file__ ).resolve()
52- CURRENT_DIR = CURRENT_FILE .parent
49+ CURRENT_DIR = Path(__file__ ).resolve().parent
5350DB_URL = f " sqlite+aiosqlite:/// { CURRENT_DIR } /db.sqlite3 "
5451
55- Base = declarative_base()
52+
53+ class Base (DeclarativeBase ):
54+ pass
5655
5756
5857class User (Base ):
5958 __tablename__ = " users"
60- id = Column(Integer, primary_key = True , autoincrement = True )
61- name = Column(Text, nullable = True )
59+
60+ id : Mapped[int ] = mapped_column(primary_key = True )
61+ name: Mapped[Optional[str ]]
6262
6363
6464class UserAttributesBaseSchema (BaseModel ):
@@ -81,38 +81,44 @@ class UserInSchema(UserAttributesBaseSchema):
8181 """ User input schema."""
8282
8383
84- def async_session () -> sessionmaker:
85- engine = create_async_engine(url = make_url(DB_URL ))
86- _async_session = sessionmaker(bind = engine, class_ = AsyncSession, expire_on_commit = False )
87- return _async_session
84+ def async_session () -> tuple[AsyncEngine, async_sessionmaker]:
85+ engine_: AsyncEngine = create_async_engine(
86+ url = f " { make_url(DB_URL )} " ,
87+ echo = True ,
88+ )
89+ session_maker_: async_sessionmaker[AsyncSession] = async_sessionmaker(
90+ autocommit = False ,
91+ bind = engine,
92+ expire_on_commit = False ,
93+ )
94+ return engine_, session_maker_
95+
96+
97+ engine, session_maker = async_session()
8898
8999
90100class Connector :
91101 @ classmethod
92- async def get_session (cls ):
93- """
94- Get session as dependency
95-
96- :return:
97- """
98- sess = async_session()
99- async with sess() as db_session: # type: AsyncSession
100- yield db_session
101- await db_session.rollback()
102+ async def dispose (cls ):
103+ await engine.dispose()
102104
105+ @ classmethod
106+ async def init (cls ) -> None :
107+ async with engine.begin() as conn:
108+ await conn.run_sync(Base.metadata.create_all)
103109
104- async def sqlalchemy_init () -> None :
105- engine = create_async_engine( url = make_url( DB_URL ))
106- async with engine.begin () as conn :
107- await conn.run_sync(Base.metadata.create_all)
110+ @ classmethod
111+ async def session ( cls ):
112+ async with session_maker () as db_session :
113+ yield db_session
108114
109115
110116class SessionDependency (BaseModel ):
111117 model_config = ConfigDict(
112118 arbitrary_types_allowed = True ,
113119 )
114120
115- session: AsyncSession = Depends(Connector.get_session )
121+ session: AsyncSession = Depends(Connector.session )
116122
117123
118124def session_dependency_handler (view : ViewBase, dto : SessionDependency) -> dict[str , Any]:
@@ -178,13 +184,15 @@ def create_app() -> FastAPI:
178184 docs_url = " /docs" ,
179185 )
180186 add_routes(app)
181- app.on_event(" startup" )(sqlalchemy_init)
187+ app.on_event(" startup" )(Connector.init)
188+ app.on_event(" shutdown" )(Connector.dispose)
182189 init(app)
183190 return app
184191
185192
186193app = create_app()
187194
195+
188196if __name__ == " __main__" :
189197 uvicorn.run(
190198 " main:app" ,
0 commit comments