[英]FastAPI database dependency setup for connection pooling
考虑以下 fastapi 设置:
application.add_event_handler(
"startup",
create_start_app_handler(application, settings),
)
def create_start_app_handler(
app: FastAPI,
settings: AppSettings,
) -> Callable:
async def start_app() -> None:
await connect_to_db(app, settings)
return start_app
async def connect_to_db(app: FastAPI, settings: AppSettings) -> None:
db_url = settings.DATABASE_URL
engine = create_engine(db_url, pool_size=settings.POOL_SIZE, max_overflow=settings.MAX_OVERFLOW)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
db = SessionLocal()
def close_db():
db.close()
engine.dispose()
app.state.db = db
app.state.close_db = close_db
close_db 用于在应用程序关闭时关闭数据库连接我定义了以下依赖项:
def _get_db(request: Request) -> Generator:
yield request.app.state.db
def get_repository(
repo_type: Type[BaseRepository],
) -> Callable[[Session], BaseRepository]:
def _get_repo(
sess: Session = Depends(_get_db),
) -> BaseRepository:
return repo_type(sess)
return _get_repo
这仍然允许我利用连接池吗?
此外,这感觉有点 hacky,如果有什么特别是我不应该做的,我可以使用一些反馈。
直言不讳; 对于文档中记录得很好的东西来说,它似乎过于复杂。
在您的情况下,您仅创建 1 个SessionLocal()
实例并将在所有请求中共享该实例(因为您将其存储在app.state
中)。 换句话说:不,这不会使用连接池,它只会使用 1 个连接。
更好的方法是通过中间件或依赖项为每个请求生成一个实例。 这样,当传入的请求被完全处理时,连接实际上是关闭的。 例如,像这样:
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.get("/")
def root(db: SessionLocal = Depends(get_db)):
return "hello world"
我不确定你是如何结束的,但我建议重构一堆。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.