FastAPI中SQLAlchemy AttributeError:'function'对象无'scalars'属性
问题:FastAPI GET请求/api/messages/触发500错误(AttributeError: 'function' object has no attribute 'scalars')
错误现象
通过SwaggerUI发送GET请求/api/messages/时触发500内部服务器错误,核心报错信息:
AttributeError: 'function' object has no attribute 'scalars'
错误堆栈
RuntimeWarning: Enable tracemalloc to get the object allocation traceback INFO: ::1:55262 - "GET /api/messages/ HTTP/1.1" 500 Internal Server Error ERROR: Exception in ASGI application Traceback (most recent call last): File "/Users/Pavel/Desktop/Projects/Messenger2/.venv/lib/python3.12/site-packages/uvicorn/protocols/http/httptools_impl.py", line 426, in run_asgi result = await app( # type: ignore[func-returns-value] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/Pavel/Desktop/Projects/Messenger2/.venv/lib/python3.12/site-packages/uvicorn/middleware/proxy_headers.py", line 84, in __call__ return await self.app(scope, receive, send) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/Pavel/Desktop/Projects/Messenger2/.venv/lib/python3.12/site-packages/fastapi/applications.py", line 1115, in __call__ await super().__call__(scope, receive, send) File "/Users/Pavel/Desktop/Projects/Messenger2/.venv/lib/python3.12/site-packages/starlette/applications.py", line 122, in __call__ await self.middleware_stack(scope, receive, send) File "/Users/Pavel/Desktop/Projects/Messenger2/.venv/lib/python3.12/site-packages/starlette/middleware/errors.py", line 184, in __call__ raise exc File "/Users/Pavel/Desktop/Projects/Messenger2/.venv/lib/python3.12/site-packages/starlette/middleware/errors.py", line 162, in __call__ await self.app(scope, receive, _send) File "/Users/Pavel/Desktop/Projects/Messenger2/.venv/lib/python3.12/site-packages/starlette/middleware/exceptions.py", line 79, in __call__ raise exc File "/Users/Pavel/Desktop/Projects/Messenger2/.venv/lib/python3.12/site-packages/starlette/middleware/exceptions.py", line 68, in __call__ await self.app(scope, receive, sender) File "/Users/Pavel/Desktop/Projects/Messenger2/.venv/lib/python3.12/site-packages/fastapi/middleware/asyncexitstack.py", line 20, in __call__ raise e File "/Users/Pavel/Desktop/Projects/Messenger2/.venv/lib/python3.12/site-packages/fastapi/middleware/asyncexitstack.py", line 17, in __call__ await self.app(scope, receive, send) File "/Users/Pavel/Desktop/Projects/Messenger2/.venv/lib/python3.12/site-packages/starlette/routing.py", line 718, in __call__ await route.handle(scope, receive, send) File "/Users/Pavel/Desktop/Projects/Messenger2/.venv/lib/python3.12/site-packages/starlette/routing.py", line 276, in handle await self.app(scope, receive, send) File "/Users/Pavel/Desktop/Projects/Messenger2/.venv/lib/python3.12/site-packages/starlette/routing.py", line 66, in app response = await func(request) ^^^^^^^^^^^^^^^^^^^ File "/Users/Pavel/Desktop/Projects/Messenger2/.venv/lib/python3.12/site-packages/fastapi/routing.py", line 274, in app raw_response = await run_endpoint_function( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/Pavel/Desktop/Projects/Messenger2/.venv/lib/python3.12/site-packages/fastapi/routing.py", line 191, in run_endpoint_function return await dependant.call(**values) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/Pavel/Desktop/Projects/Messenger2/messenger/routers/api/messages/messages.py", line 44, in list_messages return await controller.list(filters=filters) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/Pavel/Desktop/Projects/Messenger2/messenger/controllers/base.py", line 37, in list return await self.repository.list(filters=filters) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/Users/Pavel/Desktop/Projects/Messenger2/messenger/repositories/base.py", line 40, in list res = await self.session.scalars(query) ^^^^^^^^^^^^^^^^^^^^ AttributeError: 'function' object has no attribute 'scalars'
相关代码文件
messenger/routers/api/messages/messages.py
from fastapi import APIRouter, Depends from fastapi_filter import FilterDepends from typing import List from messenger.controllers import MessageController from messenger.factories import ControllerFactory from messenger.filters import MessageFilter from messenger.schemas import MessagesResponseSchema, router = APIRouter() @router.get("/") async def list_messages( controller: MessageController = Depends(ControllerFactory().get_message_controller), filters: MessageFilter = FilterDepends(MessageFilter), ) -> List[MessagesResponseSchema]: return await controller.list(filters=filters)
messenger/factories/controllers.py
from fastapi import Depends from sqlalchemy.ext.asyncio import AsyncSession from messenger.database import get_session from messenger.controllers import MessageController from messenger.models import Message from messenger.repositories import MessagesRepo class ControllerFactory: def get_message_controller(self, db_session: AsyncSession = Depends(get_session)): return MessageController( repository=MessagesRepo( db_session=get_session, model=Message, ) )
messenger/database/session.py
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker, AsyncSession from messenger.settings import settings from messenger.models import Base engine = create_async_engine( settings.get_db_url(), echo=True, ) async def get_session() -> AsyncSession: session = async_sessionmaker( bind=engine ) async with session() as db_session: try: yield db_session finally: await db_session.close()
messenger/controllers/messages.py
from .base import BaseController from messenger.models import Message from messenger.repositories import MessagesRepo class MessageController(BaseController[Message]): def __init__(self, repository: MessagesRepo): super().__init__(model=Message, repository=repository)
messenger/controllers/base.py
from fastapi_filter.contrib.sqlalchemy import Filter from sqlalchemy.sql import func from typing import Type, TypeVar, Generic, List, Any from messenger.models import Base from messenger.repositories import BaseRepo ModelType = TypeVar("ModelType", bound=Base) class BaseController(Generic[ModelType]): def __init__( self, repository: BaseRepo, model: Type[ModelType] ): self.model = model self.repository = repository async def list( self, filters: Filter, ) -> List[ModelType]: return await self.repository.list(filters=filters)
messenger/repositories/messages.py
from sqlalchemy.ext.asyncio import AsyncSession from messenger.models import Message from .base import BaseRepo class MessagesRepo(BaseRepo[Message]): def __init__(self, db_session: AsyncSession, model: Message): super().__init__(db_session=db_session, model=model)
messenger/repositories/base.py
from fastapi_filter.contrib.sqlalchemy import Filter from sqlalchemy.sql.expression import select from sqlalchemy.ext.asyncio import AsyncSession from typing import Type, TypeVar, Generic, List from messenger.models import Base from messenger.database import get_session ModelType = TypeVar("ModelType", bound=Base) class BaseRepo(Generic[ModelType]): def __init__( self, db_session: AsyncSession, model: Type[ModelType], ): self.session = db_session self.model = model async def list( self, filters: Filter, ) -> List[ModelType]: query = filters.filter(select(self.model)) res = await self.session.scalars(query) return res.all()
排查情况
查看self.session的所有方法,确认没有scalars方法,方法列表如下:
['__aenter__', '__aexit__', '__await__', '__class__', '__class_getitem__', '__delattr__', '__dir__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_assign_proxied', '_raise_for_not_started', '_regenerate_proxy_for_target', '_retrieve_proxy_for_target', '_sync_transaction', '_target_gced', 'commit', 'rollback', 'start']
已尝试操作
重新安装所有依赖,问题仍未解决,希望得到该错误的解决方案。
内容的提问来源于stack exchange,提问作者Pavel
相关产品推荐
相关产品推荐

