개발하자
FastAPI sql 모델은 데이터베이스에서 모든 행을 가져옵니다.
Cuire
2022. 11. 8. 20:13
반응형
FastAPI sql 모델은 데이터베이스에서 모든 행을 가져옵니다.
단식이 있다Postgres 13 데이터베이스에서 모든 것을 가져오기 위해 GET 경로를 제공해야 하는 API 응용 프로그램. 항목이 정의되고 다른 앱에서 추가됩니다. 항목에는 다음과 같은 모델이 있습니다.
class ItemDb(SQLModel, table=True):
__tablename__ = "items"
id: str = Field(
default_factory=uuid.uuid4, primary_key=True)
name: str
테이블도 있습니다. 모두 다음을 가리키는 외래 키를 가지고 있습니다.
class GadgetDb(SQLModel, table=True):
__tablename__ = "gadgets"
id: str = Field(
default_factory=uuid.uuid4, primary_key=True)
item_id: str = Field(..., foreign_key="items.id")
name: str
내 앱에서, 나는 일단 모든 것을 검색하고 싶다. 다음과 같은 간단한 모델을 만들었습니다.
class Item(SQLModel):
id: str
key_name: str
이것은 나의 crud 함수이다.
class CRUDItem(CRUDBase[Item, None, None]):
def list(self, db: Session) -> List[Item]:
statement = select(self.model)
results = db.exec(statement)
return results.all()
item = CRUDItem(Item)
그리고 이것이 나의 엔드포인트 기능이다.
from app.crud.crud_item import item
@router.get(
"/",
response_model=List[Item],
status_code=200,
response_model_exclude_unset=True,
)
def list_items(
session: Session = Depends(get_session),
) -> Any:
items = item.list(session)
return items
그러면 오류가 반환됩니다. 이 오류가 발생하는 이유와 데이터베이스에서 모든 행을 가져오려면 어떻게 해야 합니까?
편집. 오류 추적:
INFO: 172.30.0.1:51432 - "GET /api/v1/items/ HTTP/1.1" 500 Internal Server Error
ERROR: Exception in ASGI application
Traceback (most recent call last):
File "/usr/local/lib/python3.9/site-packages/uvicorn/protocols/http/httptools_impl.py", line 404, in run_asgi
result = await app( # type: ignore[func-returns-value]
File "/usr/local/lib/python3.9/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__
return await self.app(scope, receive, send)
File "/usr/local/lib/python3.9/site-packages/fastapi/applications.py", line 270, in __call__
await super().__call__(scope, receive, send)
File "/usr/local/lib/python3.9/site-packages/starlette/applications.py", line 124, in __call__
await self.middleware_stack(scope, receive, send)
File "/usr/local/lib/python3.9/site-packages/starlette/middleware/errors.py", line 184, in __call__
raise exc
File "/usr/local/lib/python3.9/site-packages/starlette/middleware/errors.py", line 162, in __call__
await self.app(scope, receive, _send)
File "/usr/local/lib/python3.9/site-packages/starlette/middleware/cors.py", line 84, in __call__
await self.app(scope, receive, send)
File "/usr/local/lib/python3.9/site-packages/starlette/middleware/exceptions.py", line 75, in __call__
raise exc
File "/usr/local/lib/python3.9/site-packages/starlette/middleware/exceptions.py", line 64, in __call__
await self.app(scope, receive, sender)
File "/usr/local/lib/python3.9/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__
raise e
File "/usr/local/lib/python3.9/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__
await self.app(scope, receive, send)
File "/usr/local/lib/python3.9/site-packages/starlette/routing.py", line 680, in __call__
await route.handle(scope, receive, send)
File "/usr/local/lib/python3.9/site-packages/starlette/routing.py", line 275, in handle
await self.app(scope, receive, send)
File "/usr/local/lib/python3.9/site-packages/starlette/routing.py", line 65, in app
response = await func(request)
File "/usr/local/lib/python3.9/site-packages/fastapi/routing.py", line 231, in app
raw_response = await run_endpoint_function(
File "/usr/local/lib/python3.9/site-packages/fastapi/routing.py", line 162, in run_endpoint_function
return await run_in_threadpool(dependant.call, **values)
File "/usr/local/lib/python3.9/site-packages/starlette/concurrency.py", line 41, in run_in_threadpool
return await anyio.to_thread.run_sync(func, *args)
File "/usr/local/lib/python3.9/site-packages/anyio/to_thread.py", line 31, in run_sync
return await get_asynclib().run_sync_in_worker_thread(
File "/usr/local/lib/python3.9/site-packages/anyio/_backends/_asyncio.py", line 937, in run_sync_in_worker_thread
return await future
File "/usr/local/lib/python3.9/site-packages/anyio/_backends/_asyncio.py", line 867, in run
result = context.run(func, *args)
File "/app/./app/api/api_v1/endpoints/items.py", line 29, in list_items
results = session.exec(select(Item)).all()
File "/usr/local/lib/python3.9/site-packages/sqlmodel/sql/expression.py", line 450, in select
return SelectOfScalar._create(*entities, **kw) # type: ignore
File "/usr/local/lib/python3.9/site-packages/sqlalchemy/sql/selectable.py", line 5309, in _create
return cls.create_legacy_select(*args, **kw)
File "<string>", line 2, in create_legacy_select
File "/usr/local/lib/python3.9/site-packages/sqlalchemy/util/deprecations.py", line 402, in warned
return fn(*args, **kwargs)
File "/usr/local/lib/python3.9/site-packages/sqlalchemy/sql/selectable.py", line 5165, in create_legacy_select
self._raw_columns = [
TypeError: 'ModelMetaclass' object is not iterable
편집2. 클래스:
ModelType = TypeVar("ModelType", bound=Base)
CreateSchemaType = TypeVar("CreateSchemaType", bound=BaseModel)
UpdateSchemaType = TypeVar("UpdateSchemaType", bound=BaseModel)
class CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]): # 1
def __init__(self, model: Type[ModelType]): # 2
"""
CRUD object with default methods to Create, Read, Update, Delete (CRUD).
**Parameters**
* `model`: A SQLAlchemy model class
* `schema`: A Pydantic model (schema) class
"""
self.model = model
def get(self, db: Session, id: Any) -> Optional[ModelType]:
return db.query(self.model).filter(self.model.id == id).first() # 3
def list(
self, db: Session, *, skip: int = 0, limit: int = 100
) -> List[ModelType]:
return db.query(self.model).offset(skip).limit(limit).all() # 4
def create(self, db: Session, *, obj_in: CreateSchemaType) -> ModelType:
obj_in_data = jsonable_encoder(obj_in)
db_obj = self.model(**obj_in_data) # type: ignore
db.add(db_obj)
db.commit() # 5
db.refresh(db_obj)
return db_obj
클래스는 ORM 모델(없음)이 아니므로 데이터베이스 쿼리에서 사용할 수 없습니다. 를 사용하면 문제가 해결됩니다.
반응형