gpt4 book ai didi

sqlalchemy - 如何为FastAPI应用程序编写SQLAlchemy测试装置

转载 作者:行者123 更新时间:2023-12-03 13:32:57 34 4
gpt4 key购买 nike

我正在编写一个使用SQLAlchemy数据库的FastAPI应用程序。我已经复制了example from the FastAPI documentation,为简化起见简化了数据库架构。完整的源代码在这篇文章的底部。
这行得通。我可以使用uvicorn sql_app.main:app运行它,并通过Swagger文档与数据库进行交互。运行时,它将在工作目录中创建test.db
现在,我想添加一个单元测试。这样的事情。

from fastapi import status
from fastapi.testclient import TestClient
from pytest import fixture

from main import app


@fixture
def client() -> TestClient:
return TestClient(app)


def test_fast_sql(client: TestClient):
response = client.get("/users/")
assert response.status_code == status.HTTP_200_OK
assert response.json() == []
使用下面的源代码,它将工作目录中的 test.db用作数据库。相反,我想为在测试结束时删除的每个单元测试创​​建一个新数据库。
我可以将全局 database.enginedatabase.SessionLocal放在运行时创建的对象中,如下所示:
    class UserDatabase:
def __init__(self, directory: Path):
directory.mkdir(exist_ok=True, parents=True)
sqlalchemy_database_url = f"sqlite:///{directory}/store.db"
self.engine = create_engine(
sqlalchemy_database_url, connect_args={"check_same_thread": False}
)
self.SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=self.engine)
models.Base.metadata.create_all(bind=self.engine)
但我不知道如何使它与 main.get_db一起使用,因为 Depends(get_db)逻辑最终假定 database.enginedatabase.SessionLocal在全局范围内可用。
我曾经与Flask一起工作,Flask的单元测试设备可以为您处理所有这一切。我不知道该怎么写有人可以告诉我为在此框架中为每个单元测试生成一个新数据库而必须进行的最小更改吗?

简化的FastAPI/SQLAlchemy应用程序的完整来源如下。
database.py
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

SQLALCHEMY_DATABASE_URL = "sqlite:///./test.db"

engine = create_engine(
SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

Base = declarative_base()
models.py
from sqlalchemy import Column, Integer, String

from database import Base


class User(Base):
__tablename__ = "users"

id = Column(Integer, primary_key=True, index=True)
name = Column(String)
age = Column(Integer)
schemas.py
from pydantic import BaseModel


class UserBase(BaseModel):
name: str
age: int


class UserCreate(UserBase):
pass


class User(UserBase):
id: int

class Config:
orm_mode = True
crud.py
from sqlalchemy.orm import Session

import schemas
import models


def get_user(db: Session, user_id: int):
return db.query(models.User).filter(models.User.id == user_id).first()


def get_users(db: Session, skip: int = 0, limit: int = 100):
return db.query(models.User).offset(skip).limit(limit).all()


def create_user(db: Session, user: schemas.UserCreate):
db_user = models.User(name=user.name, age=user.age)
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user
main.py
from typing import List

from fastapi import Depends, FastAPI, HTTPException
from sqlalchemy.orm import Session

import schemas
import models
import crud
from database import SessionLocal, engine

models.Base.metadata.create_all(bind=engine)

app = FastAPI()


# Dependency
def get_db():
try:
db = SessionLocal()
yield db
finally:
db.close()


@app.post("/users/", response_model=schemas.User)
def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):
return crud.create_user(db=db, user=user)


@app.get("/users/", response_model=List[schemas.User])
def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
users = crud.get_users(db, skip=skip, limit=limit)
return users


@app.get("/users/{user_id}", response_model=schemas.User)
def read_user(user_id: int, db: Session = Depends(get_db)):
db_user = crud.get_user(db, user_id=user_id)
if db_user is None:
raise HTTPException(status_code=404, detail="User not found")
return db_user

最佳答案

您需要在测试中覆盖get_db依赖性,请参阅these docs
对于您的装置,像这样的东西:

@fixture
def db_fixture() -> Session:
raise NotImplementError() # Make this return your temporary session

@fixture
def client(db_fixture) -> TestClient:

def _get_db_override():
return db_fixture

app.dependency_overrides[get_db] = _get_db_override
return TestClient(app)

关于sqlalchemy - 如何为FastAPI应用程序编写SQLAlchemy测试装置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60711576/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com