在 FastAPI 中连接数据库的最佳方法是什么?

muo*_*uon 8 python rest fastapi

我发现了两种在 FastAPI 中使用数据库的方法。有什么根本区别吗?如果是这样,哪种方法更可取?

方法 1 这是在官方 FastAPI-fullstack 示例中找到的:

from fastapi import Depends
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine

engine = create_engine(SQLALCHEMY_DATABASE_URI, pool_pre_ping=True)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

def get_db() -> Generator:
    try:
        db = SessionLocal()
        yield db
    finally:
        db.close()


def get_current_user(
    db: Session = Depends(get_db), token: str = Depends(reusable_oauth2)
) -> models.User:
    ...

Run Code Online (Sandbox Code Playgroud)

方法 2在官方FastAPI 文档、一些博客以及包文档 中找到以下方法fastapi_users

import databases

DATABASE_URL = "sqlite:///./test.db"
database = databases.Database(DATABASE_URL)

@app.on_event("startup")
async def startup():
    await database.connect()


@app.on_event("shutdown")
async def shutdown():
    await database.disconnect()

Run Code Online (Sandbox Code Playgroud)

编辑 (2021-09-06) - 方法 3

tiangolo 本人在新的 SQLModel 包文档中推荐的另一种方法。这似乎只是上述第一种方法的变体,但为了完整起见:

https://sqlmodel.tiangolo.com/tutorial/fastapi/session-with-dependency/

sqlite_file_name = "database.db"
sqlite_url = f"sqlite:///{sqlite_file_name}"

connect_args = {"check_same_thread": False}
engine = create_engine(sqlite_url, echo=True, connect_args=connect_args)

def get_session():
    with Session(engine) as session:
        yield session

# Code here omitted 

@app.post("/heroes/", response_model=HeroRead)
def create_hero(*, session: Session = Depends(get_session), hero: HeroCreate):
    db_hero = Hero.from_orm(hero)
    session.add(db_hero)
    session.commit()
    session.refresh(db_hero)
    return db_hero

Run Code Online (Sandbox Code Playgroud)