From 0a2f0cb146912ab021e6d51bb9e7ef79cac207cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=81=E5=AE=B6=E5=AF=85?= <15277360553@163.com> Date: Thu, 10 Sep 2026 23:15:37 +0800 Subject: [PATCH 1/2] =?UTF-8?q?feat:=E6=96=B0=E5=A2=9E=E5=9F=BA=E9=87=91?= =?UTF-8?q?=E4=BA=A7=E5=93=81=E5=88=97=E8=A1=A8=E6=8E=A5=E5=8F=A3,?= =?UTF-8?q?=E5=8E=86=E5=8F=B2=E4=B8=9A=E7=BB=A9=E6=8E=A5=E5=8F=A3,?= =?UTF-8?q?=E5=AE=A2=E6=88=B7=E6=B3=A8=E5=86=8C=E6=8F=90=E4=BA=A4=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3,=E9=97=AE=E5=8D=B7=E6=8F=90=E4=BA=A4=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/Mutual_Fund.iml | 2 +- .idea/misc.xml | 2 +- api/router.py | 4 +- api/routers/auth.py | 14 +- logs/error.log | 851 +++++++++++++++++++++++++++++++++++++++ logs/info.log | 851 +++++++++++++++++++++++++++++++++++++++ repositories/sys_user.py | 5 +- requirements.txt | 22 +- schemas/auth.py | 9 +- service/auth.py | 28 +- sql/schema.sql | 1 - 11 files changed, 1767 insertions(+), 22 deletions(-) diff --git a/.idea/Mutual_Fund.iml b/.idea/Mutual_Fund.iml index 3fbabf5..7b59439 100644 --- a/.idea/Mutual_Fund.iml +++ b/.idea/Mutual_Fund.iml @@ -4,7 +4,7 @@ - + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 7440d61..34dc9d9 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -3,5 +3,5 @@ - + \ No newline at end of file diff --git a/api/router.py b/api/router.py index f199e06..3d132d6 100644 --- a/api/router.py +++ b/api/router.py @@ -3,7 +3,9 @@ """ from fastapi import APIRouter -from api.routers import auth +from api.routers import auth, product, questionnaire api_router = APIRouter() api_router.include_router(auth.router, prefix="/api", tags=["认证"]) +api_router.include_router(product.router, prefix="/api", tags=["产品"]) +api_router.include_router(questionnaire.router, prefix="/api", tags=["问卷"]) diff --git a/api/routers/auth.py b/api/routers/auth.py index df51975..0bb0891 100644 --- a/api/routers/auth.py +++ b/api/routers/auth.py @@ -1,12 +1,13 @@ -"""认证路由:登录 + 当前用户(业务在 service/auth.py,路由只做编排)。""" +"""认证路由:登录 + 注册 + 当前用户(业务在 service/auth.py,路由只做编排)。""" from fastapi import APIRouter, Depends from sqlalchemy.ext.asyncio import AsyncSession from api.deps import get_current_user from config.deps import get_db from model.sys_user import SysUser -from schemas.auth import LoginReq +from schemas.auth import LoginReq, RegisterReq from service.auth import login as auth_login +from service.auth import register as auth_register from service.auth import user_payload from utils.response import success @@ -18,7 +19,14 @@ async def login(body: LoginReq, db: AsyncSession = Depends(get_db)): return success(await auth_login(db, body.username, body.password)) +@router.post("/auth/register") +async def register(body: RegisterReq, db: AsyncSession = Depends(get_db)): + return success( + await auth_register(db, body.username, body.password, body.phone, body.real_name) + ) + + @router.get("/auth/me") async def me(user: SysUser = Depends(get_current_user)): """受保护示例路由:任意接口加 Depends(get_current_user) 即获得当前用户。""" - return success({"user": user_payload(user)}) \ No newline at end of file + return success({"user": user_payload(user)}) diff --git a/logs/error.log b/logs/error.log index ddccd54..428d8f4 100644 --- a/logs/error.log +++ b/logs/error.log @@ -403,3 +403,854 @@ Traceback (most recent call last): self._write_fut = self._loop._proactor.send(self._sock, data) ^^^^^^^^^^^^^^^^^^^^^^^^^ AttributeError: 'NoneType' object has no attribute 'send' +2026-09-10 20:49:20,257 ERROR [-] api: unhandled error on /api/auth/login +Traceback (most recent call last): + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\api\routers\auth.py", line 19, in login + return success(await auth_login(db, body.username, body.password)) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\service\auth.py", line 68, in login + user = await SysUserRepo(db).get_by_username(username) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\repositories\sys_user.py", line 14, in get_by_username + return await self.db.scalar(select(SysUser).where(SysUser.username == username)) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\ext\asyncio\session.py", line 504, in scalar + return await greenlet_spawn( + ^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 201, in greenlet_spawn + result = context.throw(*sys.exc_info()) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2421, in scalar + return self._execute_internal( + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2261, in _execute_internal + conn = self._connection_for_bind(bind) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2113, in _connection_for_bind + return trans._connection_for_bind(engine, execution_options) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "", line 2, in _connection_for_bind + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\state_changes.py", line 137, in _go + ret_value = fn(self, *arg, **kw) + ^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 1191, in _connection_for_bind + conn = bind.connect() + ^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 3295, in connect + return self._connection_cls(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 144, in __init__ + self._dbapi_connection = engine.raw_connection() + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 3319, in raw_connection + return self.pool.connect() + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 448, in connect + return _ConnectionFairy._checkout(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 1272, in _checkout + fairy = _ConnectionRecord.checkout(pool) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 712, in checkout + rec = pool._do_get() + ^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 178, in _do_get + with util.safe_reraise(): + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 122, in __exit__ + raise exc_value.with_traceback(exc_tb) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 176, in _do_get + return self._create_connection() + ^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 389, in _create_connection + return _ConnectionRecord(self) + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 674, in __init__ + self.__connect() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 900, in __connect + with util.safe_reraise(): + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 122, in __exit__ + raise exc_value.with_traceback(exc_tb) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 896, in __connect + self.dbapi_connection = connection = pool._invoke_creator(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\create.py", line 667, in connect + return dialect.connect(*cargs_tup, **cparams) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\default.py", line 630, in connect + return self.loaded_dbapi.connect(*cargs, **cparams) # type: ignore[no-any-return] # NOQA: E501 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\dialects\mysql\aiomysql.py", line 176, in connect + await_only(creator_fn(*arg, **kw)), + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 132, in await_only + return current.parent.switch(awaitable) # type: ignore[no-any-return,attr-defined] # noqa: E501 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 196, in greenlet_spawn + value = await result + ^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 74, in _connect + await conn._connect() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 540, in _connect + await self._request_authentication() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 865, in _request_authentication + await self.caching_sha2_password_auth(auth_packet) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 984, in caching_sha2_password_auth + data = _auth.sha2_rsa_encrypt( + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\pymysql\_auth.py", line 144, in sha2_rsa_encrypt + raise RuntimeError( +RuntimeError: 'cryptography' package is required for sha256_password or caching_sha2_password auth methods +2026-09-10 20:50:16,723 ERROR [-] api: unhandled error on /api/auth/login +Traceback (most recent call last): + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 144, in __init__ + self._dbapi_connection = engine.raw_connection() + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 3319, in raw_connection + return self.pool.connect() + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 448, in connect + return _ConnectionFairy._checkout(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 1272, in _checkout + fairy = _ConnectionRecord.checkout(pool) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 712, in checkout + rec = pool._do_get() + ^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 178, in _do_get + with util.safe_reraise(): + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 122, in __exit__ + raise exc_value.with_traceback(exc_tb) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 176, in _do_get + return self._create_connection() + ^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 389, in _create_connection + return _ConnectionRecord(self) + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 674, in __init__ + self.__connect() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 900, in __connect + with util.safe_reraise(): + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 122, in __exit__ + raise exc_value.with_traceback(exc_tb) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 896, in __connect + self.dbapi_connection = connection = pool._invoke_creator(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\create.py", line 667, in connect + return dialect.connect(*cargs_tup, **cparams) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\default.py", line 630, in connect + return self.loaded_dbapi.connect(*cargs, **cparams) # type: ignore[no-any-return] # NOQA: E501 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\dialects\mysql\aiomysql.py", line 176, in connect + await_only(creator_fn(*arg, **kw)), + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 132, in await_only + return current.parent.switch(awaitable) # type: ignore[no-any-return,attr-defined] # noqa: E501 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 196, in greenlet_spawn + value = await result + ^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 74, in _connect + await conn._connect() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 540, in _connect + await self._request_authentication() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 865, in _request_authentication + await self.caching_sha2_password_auth(auth_packet) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 989, in caching_sha2_password_auth + pkt = await self._read_packet() + ^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 652, in _read_packet + packet.raise_for_error() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\pymysql\protocol.py", line 219, in raise_for_error + err.raise_mysql_exception(self._data) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\pymysql\err.py", line 154, in raise_mysql_exception + raise errorclass(errno, errval, sqlstate=sqlstate) +pymysql.err.OperationalError: (1049, "Unknown database 'memory'") + +The above exception was the direct cause of the following exception: + +Traceback (most recent call last): + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\api\routers\auth.py", line 19, in login + return success(await auth_login(db, body.username, body.password)) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\service\auth.py", line 68, in login + user = await SysUserRepo(db).get_by_username(username) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\repositories\sys_user.py", line 14, in get_by_username + return await self.db.scalar(select(SysUser).where(SysUser.username == username)) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\ext\asyncio\session.py", line 504, in scalar + return await greenlet_spawn( + ^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 201, in greenlet_spawn + result = context.throw(*sys.exc_info()) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2421, in scalar + return self._execute_internal( + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2261, in _execute_internal + conn = self._connection_for_bind(bind) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2113, in _connection_for_bind + return trans._connection_for_bind(engine, execution_options) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "", line 2, in _connection_for_bind + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\state_changes.py", line 137, in _go + ret_value = fn(self, *arg, **kw) + ^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 1191, in _connection_for_bind + conn = bind.connect() + ^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 3295, in connect + return self._connection_cls(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 146, in __init__ + Connection._handle_dbapi_exception_noconnection( + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 2450, in _handle_dbapi_exception_noconnection + raise sqlalchemy_exception.with_traceback(exc_info[2]) from e + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 144, in __init__ + self._dbapi_connection = engine.raw_connection() + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 3319, in raw_connection + return self.pool.connect() + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 448, in connect + return _ConnectionFairy._checkout(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 1272, in _checkout + fairy = _ConnectionRecord.checkout(pool) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 712, in checkout + rec = pool._do_get() + ^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 178, in _do_get + with util.safe_reraise(): + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 122, in __exit__ + raise exc_value.with_traceback(exc_tb) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 176, in _do_get + return self._create_connection() + ^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 389, in _create_connection + return _ConnectionRecord(self) + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 674, in __init__ + self.__connect() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 900, in __connect + with util.safe_reraise(): + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 122, in __exit__ + raise exc_value.with_traceback(exc_tb) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 896, in __connect + self.dbapi_connection = connection = pool._invoke_creator(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\create.py", line 667, in connect + return dialect.connect(*cargs_tup, **cparams) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\default.py", line 630, in connect + return self.loaded_dbapi.connect(*cargs, **cparams) # type: ignore[no-any-return] # NOQA: E501 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\dialects\mysql\aiomysql.py", line 176, in connect + await_only(creator_fn(*arg, **kw)), + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 132, in await_only + return current.parent.switch(awaitable) # type: ignore[no-any-return,attr-defined] # noqa: E501 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 196, in greenlet_spawn + value = await result + ^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 74, in _connect + await conn._connect() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 540, in _connect + await self._request_authentication() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 865, in _request_authentication + await self.caching_sha2_password_auth(auth_packet) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 989, in caching_sha2_password_auth + pkt = await self._read_packet() + ^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 652, in _read_packet + packet.raise_for_error() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\pymysql\protocol.py", line 219, in raise_for_error + err.raise_mysql_exception(self._data) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\pymysql\err.py", line 154, in raise_mysql_exception + raise errorclass(errno, errval, sqlstate=sqlstate) +sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (1049, "Unknown database 'memory'") +(Background on this error at: https://sqlalche.me/e/20/e3q8) +2026-09-10 20:51:21,189 ERROR [-] api: unhandled error on /api/auth/login +Traceback (most recent call last): + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 144, in __init__ + self._dbapi_connection = engine.raw_connection() + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 3319, in raw_connection + return self.pool.connect() + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 448, in connect + return _ConnectionFairy._checkout(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 1272, in _checkout + fairy = _ConnectionRecord.checkout(pool) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 712, in checkout + rec = pool._do_get() + ^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 178, in _do_get + with util.safe_reraise(): + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 122, in __exit__ + raise exc_value.with_traceback(exc_tb) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 176, in _do_get + return self._create_connection() + ^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 389, in _create_connection + return _ConnectionRecord(self) + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 674, in __init__ + self.__connect() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 900, in __connect + with util.safe_reraise(): + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 122, in __exit__ + raise exc_value.with_traceback(exc_tb) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 896, in __connect + self.dbapi_connection = connection = pool._invoke_creator(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\create.py", line 667, in connect + return dialect.connect(*cargs_tup, **cparams) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\default.py", line 630, in connect + return self.loaded_dbapi.connect(*cargs, **cparams) # type: ignore[no-any-return] # NOQA: E501 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\dialects\mysql\aiomysql.py", line 176, in connect + await_only(creator_fn(*arg, **kw)), + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 132, in await_only + return current.parent.switch(awaitable) # type: ignore[no-any-return,attr-defined] # noqa: E501 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 196, in greenlet_spawn + value = await result + ^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 74, in _connect + await conn._connect() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 540, in _connect + await self._request_authentication() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 865, in _request_authentication + await self.caching_sha2_password_auth(auth_packet) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 952, in caching_sha2_password_auth + pkt = await self._read_packet() + ^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 652, in _read_packet + packet.raise_for_error() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\pymysql\protocol.py", line 219, in raise_for_error + err.raise_mysql_exception(self._data) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\pymysql\err.py", line 154, in raise_mysql_exception + raise errorclass(errno, errval, sqlstate=sqlstate) +pymysql.err.OperationalError: (1049, "Unknown database 'memory'") + +The above exception was the direct cause of the following exception: + +Traceback (most recent call last): + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\api\routers\auth.py", line 19, in login + return success(await auth_login(db, body.username, body.password)) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\service\auth.py", line 68, in login + user = await SysUserRepo(db).get_by_username(username) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\repositories\sys_user.py", line 14, in get_by_username + return await self.db.scalar(select(SysUser).where(SysUser.username == username)) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\ext\asyncio\session.py", line 504, in scalar + return await greenlet_spawn( + ^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 201, in greenlet_spawn + result = context.throw(*sys.exc_info()) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2421, in scalar + return self._execute_internal( + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2261, in _execute_internal + conn = self._connection_for_bind(bind) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2113, in _connection_for_bind + return trans._connection_for_bind(engine, execution_options) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "", line 2, in _connection_for_bind + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\state_changes.py", line 137, in _go + ret_value = fn(self, *arg, **kw) + ^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 1191, in _connection_for_bind + conn = bind.connect() + ^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 3295, in connect + return self._connection_cls(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 146, in __init__ + Connection._handle_dbapi_exception_noconnection( + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 2450, in _handle_dbapi_exception_noconnection + raise sqlalchemy_exception.with_traceback(exc_info[2]) from e + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 144, in __init__ + self._dbapi_connection = engine.raw_connection() + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 3319, in raw_connection + return self.pool.connect() + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 448, in connect + return _ConnectionFairy._checkout(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 1272, in _checkout + fairy = _ConnectionRecord.checkout(pool) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 712, in checkout + rec = pool._do_get() + ^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 178, in _do_get + with util.safe_reraise(): + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 122, in __exit__ + raise exc_value.with_traceback(exc_tb) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 176, in _do_get + return self._create_connection() + ^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 389, in _create_connection + return _ConnectionRecord(self) + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 674, in __init__ + self.__connect() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 900, in __connect + with util.safe_reraise(): + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 122, in __exit__ + raise exc_value.with_traceback(exc_tb) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 896, in __connect + self.dbapi_connection = connection = pool._invoke_creator(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\create.py", line 667, in connect + return dialect.connect(*cargs_tup, **cparams) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\default.py", line 630, in connect + return self.loaded_dbapi.connect(*cargs, **cparams) # type: ignore[no-any-return] # NOQA: E501 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\dialects\mysql\aiomysql.py", line 176, in connect + await_only(creator_fn(*arg, **kw)), + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 132, in await_only + return current.parent.switch(awaitable) # type: ignore[no-any-return,attr-defined] # noqa: E501 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 196, in greenlet_spawn + value = await result + ^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 74, in _connect + await conn._connect() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 540, in _connect + await self._request_authentication() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 865, in _request_authentication + await self.caching_sha2_password_auth(auth_packet) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 952, in caching_sha2_password_auth + pkt = await self._read_packet() + ^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 652, in _read_packet + packet.raise_for_error() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\pymysql\protocol.py", line 219, in raise_for_error + err.raise_mysql_exception(self._data) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\pymysql\err.py", line 154, in raise_mysql_exception + raise errorclass(errno, errval, sqlstate=sqlstate) +sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (1049, "Unknown database 'memory'") +(Background on this error at: https://sqlalche.me/e/20/e3q8) +2026-09-10 21:54:16,943 ERROR [-] api: unhandled error on /api/products +Traceback (most recent call last): + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 144, in __init__ + self._dbapi_connection = engine.raw_connection() + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 3319, in raw_connection + return self.pool.connect() + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 448, in connect + return _ConnectionFairy._checkout(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 1272, in _checkout + fairy = _ConnectionRecord.checkout(pool) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 712, in checkout + rec = pool._do_get() + ^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 178, in _do_get + with util.safe_reraise(): + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 122, in __exit__ + raise exc_value.with_traceback(exc_tb) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 176, in _do_get + return self._create_connection() + ^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 389, in _create_connection + return _ConnectionRecord(self) + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 674, in __init__ + self.__connect() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 900, in __connect + with util.safe_reraise(): + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 122, in __exit__ + raise exc_value.with_traceback(exc_tb) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 896, in __connect + self.dbapi_connection = connection = pool._invoke_creator(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\create.py", line 667, in connect + return dialect.connect(*cargs_tup, **cparams) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\default.py", line 630, in connect + return self.loaded_dbapi.connect(*cargs, **cparams) # type: ignore[no-any-return] # NOQA: E501 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\dialects\mysql\aiomysql.py", line 176, in connect + await_only(creator_fn(*arg, **kw)), + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 132, in await_only + return current.parent.switch(awaitable) # type: ignore[no-any-return,attr-defined] # noqa: E501 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 196, in greenlet_spawn + value = await result + ^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 74, in _connect + await conn._connect() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 540, in _connect + await self._request_authentication() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 865, in _request_authentication + await self.caching_sha2_password_auth(auth_packet) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 989, in caching_sha2_password_auth + pkt = await self._read_packet() + ^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 652, in _read_packet + packet.raise_for_error() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\pymysql\protocol.py", line 219, in raise_for_error + err.raise_mysql_exception(self._data) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\pymysql\err.py", line 154, in raise_mysql_exception + raise errorclass(errno, errval, sqlstate=sqlstate) +pymysql.err.OperationalError: (1045, "Access denied for user 'root'@'localhost' (using password: YES)") + +The above exception was the direct cause of the following exception: + +Traceback (most recent call last): + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\api\routers\product.py", line 26, in products + data = await list_products( + ^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\service\product.py", line 54, in list_products + items, total = await ProductRepo(db).search( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\repositories\product.py", line 64, in search + items = list((await self.db.scalars(stmt)).all()) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\ext\asyncio\session.py", line 561, in scalars + result = await self.execute( + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\ext\asyncio\session.py", line 448, in execute + result = await greenlet_spawn( + ^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 201, in greenlet_spawn + result = context.throw(*sys.exc_info()) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2373, in execute + return self._execute_internal( + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2261, in _execute_internal + conn = self._connection_for_bind(bind) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2113, in _connection_for_bind + return trans._connection_for_bind(engine, execution_options) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "", line 2, in _connection_for_bind + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\state_changes.py", line 137, in _go + ret_value = fn(self, *arg, **kw) + ^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 1191, in _connection_for_bind + conn = bind.connect() + ^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 3295, in connect + return self._connection_cls(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 146, in __init__ + Connection._handle_dbapi_exception_noconnection( + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 2450, in _handle_dbapi_exception_noconnection + raise sqlalchemy_exception.with_traceback(exc_info[2]) from e + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 144, in __init__ + self._dbapi_connection = engine.raw_connection() + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 3319, in raw_connection + return self.pool.connect() + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 448, in connect + return _ConnectionFairy._checkout(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 1272, in _checkout + fairy = _ConnectionRecord.checkout(pool) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 712, in checkout + rec = pool._do_get() + ^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 178, in _do_get + with util.safe_reraise(): + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 122, in __exit__ + raise exc_value.with_traceback(exc_tb) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 176, in _do_get + return self._create_connection() + ^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 389, in _create_connection + return _ConnectionRecord(self) + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 674, in __init__ + self.__connect() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 900, in __connect + with util.safe_reraise(): + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 122, in __exit__ + raise exc_value.with_traceback(exc_tb) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 896, in __connect + self.dbapi_connection = connection = pool._invoke_creator(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\create.py", line 667, in connect + return dialect.connect(*cargs_tup, **cparams) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\default.py", line 630, in connect + return self.loaded_dbapi.connect(*cargs, **cparams) # type: ignore[no-any-return] # NOQA: E501 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\dialects\mysql\aiomysql.py", line 176, in connect + await_only(creator_fn(*arg, **kw)), + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 132, in await_only + return current.parent.switch(awaitable) # type: ignore[no-any-return,attr-defined] # noqa: E501 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 196, in greenlet_spawn + value = await result + ^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 74, in _connect + await conn._connect() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 540, in _connect + await self._request_authentication() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 865, in _request_authentication + await self.caching_sha2_password_auth(auth_packet) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 989, in caching_sha2_password_auth + pkt = await self._read_packet() + ^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 652, in _read_packet + packet.raise_for_error() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\pymysql\protocol.py", line 219, in raise_for_error + err.raise_mysql_exception(self._data) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\pymysql\err.py", line 154, in raise_mysql_exception + raise errorclass(errno, errval, sqlstate=sqlstate) +sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (1045, "Access denied for user 'root'@'localhost' (using password: YES)") +(Background on this error at: https://sqlalche.me/e/20/e3q8) diff --git a/logs/info.log b/logs/info.log index e25fec3..7a4fbc2 100644 --- a/logs/info.log +++ b/logs/info.log @@ -412,3 +412,854 @@ Traceback (most recent call last): self._write_fut = self._loop._proactor.send(self._sock, data) ^^^^^^^^^^^^^^^^^^^^^^^^^ AttributeError: 'NoneType' object has no attribute 'send' +2026-09-10 20:49:20,257 ERROR [-] api: unhandled error on /api/auth/login +Traceback (most recent call last): + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\api\routers\auth.py", line 19, in login + return success(await auth_login(db, body.username, body.password)) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\service\auth.py", line 68, in login + user = await SysUserRepo(db).get_by_username(username) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\repositories\sys_user.py", line 14, in get_by_username + return await self.db.scalar(select(SysUser).where(SysUser.username == username)) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\ext\asyncio\session.py", line 504, in scalar + return await greenlet_spawn( + ^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 201, in greenlet_spawn + result = context.throw(*sys.exc_info()) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2421, in scalar + return self._execute_internal( + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2261, in _execute_internal + conn = self._connection_for_bind(bind) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2113, in _connection_for_bind + return trans._connection_for_bind(engine, execution_options) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "", line 2, in _connection_for_bind + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\state_changes.py", line 137, in _go + ret_value = fn(self, *arg, **kw) + ^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 1191, in _connection_for_bind + conn = bind.connect() + ^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 3295, in connect + return self._connection_cls(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 144, in __init__ + self._dbapi_connection = engine.raw_connection() + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 3319, in raw_connection + return self.pool.connect() + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 448, in connect + return _ConnectionFairy._checkout(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 1272, in _checkout + fairy = _ConnectionRecord.checkout(pool) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 712, in checkout + rec = pool._do_get() + ^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 178, in _do_get + with util.safe_reraise(): + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 122, in __exit__ + raise exc_value.with_traceback(exc_tb) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 176, in _do_get + return self._create_connection() + ^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 389, in _create_connection + return _ConnectionRecord(self) + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 674, in __init__ + self.__connect() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 900, in __connect + with util.safe_reraise(): + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 122, in __exit__ + raise exc_value.with_traceback(exc_tb) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 896, in __connect + self.dbapi_connection = connection = pool._invoke_creator(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\create.py", line 667, in connect + return dialect.connect(*cargs_tup, **cparams) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\default.py", line 630, in connect + return self.loaded_dbapi.connect(*cargs, **cparams) # type: ignore[no-any-return] # NOQA: E501 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\dialects\mysql\aiomysql.py", line 176, in connect + await_only(creator_fn(*arg, **kw)), + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 132, in await_only + return current.parent.switch(awaitable) # type: ignore[no-any-return,attr-defined] # noqa: E501 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 196, in greenlet_spawn + value = await result + ^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 74, in _connect + await conn._connect() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 540, in _connect + await self._request_authentication() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 865, in _request_authentication + await self.caching_sha2_password_auth(auth_packet) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 984, in caching_sha2_password_auth + data = _auth.sha2_rsa_encrypt( + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\pymysql\_auth.py", line 144, in sha2_rsa_encrypt + raise RuntimeError( +RuntimeError: 'cryptography' package is required for sha256_password or caching_sha2_password auth methods +2026-09-10 20:50:16,723 ERROR [-] api: unhandled error on /api/auth/login +Traceback (most recent call last): + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 144, in __init__ + self._dbapi_connection = engine.raw_connection() + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 3319, in raw_connection + return self.pool.connect() + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 448, in connect + return _ConnectionFairy._checkout(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 1272, in _checkout + fairy = _ConnectionRecord.checkout(pool) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 712, in checkout + rec = pool._do_get() + ^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 178, in _do_get + with util.safe_reraise(): + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 122, in __exit__ + raise exc_value.with_traceback(exc_tb) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 176, in _do_get + return self._create_connection() + ^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 389, in _create_connection + return _ConnectionRecord(self) + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 674, in __init__ + self.__connect() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 900, in __connect + with util.safe_reraise(): + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 122, in __exit__ + raise exc_value.with_traceback(exc_tb) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 896, in __connect + self.dbapi_connection = connection = pool._invoke_creator(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\create.py", line 667, in connect + return dialect.connect(*cargs_tup, **cparams) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\default.py", line 630, in connect + return self.loaded_dbapi.connect(*cargs, **cparams) # type: ignore[no-any-return] # NOQA: E501 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\dialects\mysql\aiomysql.py", line 176, in connect + await_only(creator_fn(*arg, **kw)), + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 132, in await_only + return current.parent.switch(awaitable) # type: ignore[no-any-return,attr-defined] # noqa: E501 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 196, in greenlet_spawn + value = await result + ^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 74, in _connect + await conn._connect() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 540, in _connect + await self._request_authentication() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 865, in _request_authentication + await self.caching_sha2_password_auth(auth_packet) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 989, in caching_sha2_password_auth + pkt = await self._read_packet() + ^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 652, in _read_packet + packet.raise_for_error() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\pymysql\protocol.py", line 219, in raise_for_error + err.raise_mysql_exception(self._data) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\pymysql\err.py", line 154, in raise_mysql_exception + raise errorclass(errno, errval, sqlstate=sqlstate) +pymysql.err.OperationalError: (1049, "Unknown database 'memory'") + +The above exception was the direct cause of the following exception: + +Traceback (most recent call last): + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\api\routers\auth.py", line 19, in login + return success(await auth_login(db, body.username, body.password)) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\service\auth.py", line 68, in login + user = await SysUserRepo(db).get_by_username(username) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\repositories\sys_user.py", line 14, in get_by_username + return await self.db.scalar(select(SysUser).where(SysUser.username == username)) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\ext\asyncio\session.py", line 504, in scalar + return await greenlet_spawn( + ^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 201, in greenlet_spawn + result = context.throw(*sys.exc_info()) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2421, in scalar + return self._execute_internal( + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2261, in _execute_internal + conn = self._connection_for_bind(bind) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2113, in _connection_for_bind + return trans._connection_for_bind(engine, execution_options) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "", line 2, in _connection_for_bind + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\state_changes.py", line 137, in _go + ret_value = fn(self, *arg, **kw) + ^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 1191, in _connection_for_bind + conn = bind.connect() + ^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 3295, in connect + return self._connection_cls(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 146, in __init__ + Connection._handle_dbapi_exception_noconnection( + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 2450, in _handle_dbapi_exception_noconnection + raise sqlalchemy_exception.with_traceback(exc_info[2]) from e + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 144, in __init__ + self._dbapi_connection = engine.raw_connection() + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 3319, in raw_connection + return self.pool.connect() + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 448, in connect + return _ConnectionFairy._checkout(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 1272, in _checkout + fairy = _ConnectionRecord.checkout(pool) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 712, in checkout + rec = pool._do_get() + ^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 178, in _do_get + with util.safe_reraise(): + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 122, in __exit__ + raise exc_value.with_traceback(exc_tb) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 176, in _do_get + return self._create_connection() + ^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 389, in _create_connection + return _ConnectionRecord(self) + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 674, in __init__ + self.__connect() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 900, in __connect + with util.safe_reraise(): + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 122, in __exit__ + raise exc_value.with_traceback(exc_tb) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 896, in __connect + self.dbapi_connection = connection = pool._invoke_creator(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\create.py", line 667, in connect + return dialect.connect(*cargs_tup, **cparams) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\default.py", line 630, in connect + return self.loaded_dbapi.connect(*cargs, **cparams) # type: ignore[no-any-return] # NOQA: E501 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\dialects\mysql\aiomysql.py", line 176, in connect + await_only(creator_fn(*arg, **kw)), + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 132, in await_only + return current.parent.switch(awaitable) # type: ignore[no-any-return,attr-defined] # noqa: E501 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 196, in greenlet_spawn + value = await result + ^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 74, in _connect + await conn._connect() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 540, in _connect + await self._request_authentication() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 865, in _request_authentication + await self.caching_sha2_password_auth(auth_packet) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 989, in caching_sha2_password_auth + pkt = await self._read_packet() + ^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 652, in _read_packet + packet.raise_for_error() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\pymysql\protocol.py", line 219, in raise_for_error + err.raise_mysql_exception(self._data) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\pymysql\err.py", line 154, in raise_mysql_exception + raise errorclass(errno, errval, sqlstate=sqlstate) +sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (1049, "Unknown database 'memory'") +(Background on this error at: https://sqlalche.me/e/20/e3q8) +2026-09-10 20:51:21,189 ERROR [-] api: unhandled error on /api/auth/login +Traceback (most recent call last): + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 144, in __init__ + self._dbapi_connection = engine.raw_connection() + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 3319, in raw_connection + return self.pool.connect() + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 448, in connect + return _ConnectionFairy._checkout(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 1272, in _checkout + fairy = _ConnectionRecord.checkout(pool) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 712, in checkout + rec = pool._do_get() + ^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 178, in _do_get + with util.safe_reraise(): + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 122, in __exit__ + raise exc_value.with_traceback(exc_tb) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 176, in _do_get + return self._create_connection() + ^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 389, in _create_connection + return _ConnectionRecord(self) + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 674, in __init__ + self.__connect() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 900, in __connect + with util.safe_reraise(): + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 122, in __exit__ + raise exc_value.with_traceback(exc_tb) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 896, in __connect + self.dbapi_connection = connection = pool._invoke_creator(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\create.py", line 667, in connect + return dialect.connect(*cargs_tup, **cparams) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\default.py", line 630, in connect + return self.loaded_dbapi.connect(*cargs, **cparams) # type: ignore[no-any-return] # NOQA: E501 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\dialects\mysql\aiomysql.py", line 176, in connect + await_only(creator_fn(*arg, **kw)), + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 132, in await_only + return current.parent.switch(awaitable) # type: ignore[no-any-return,attr-defined] # noqa: E501 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 196, in greenlet_spawn + value = await result + ^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 74, in _connect + await conn._connect() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 540, in _connect + await self._request_authentication() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 865, in _request_authentication + await self.caching_sha2_password_auth(auth_packet) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 952, in caching_sha2_password_auth + pkt = await self._read_packet() + ^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 652, in _read_packet + packet.raise_for_error() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\pymysql\protocol.py", line 219, in raise_for_error + err.raise_mysql_exception(self._data) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\pymysql\err.py", line 154, in raise_mysql_exception + raise errorclass(errno, errval, sqlstate=sqlstate) +pymysql.err.OperationalError: (1049, "Unknown database 'memory'") + +The above exception was the direct cause of the following exception: + +Traceback (most recent call last): + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\api\routers\auth.py", line 19, in login + return success(await auth_login(db, body.username, body.password)) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\service\auth.py", line 68, in login + user = await SysUserRepo(db).get_by_username(username) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\repositories\sys_user.py", line 14, in get_by_username + return await self.db.scalar(select(SysUser).where(SysUser.username == username)) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\ext\asyncio\session.py", line 504, in scalar + return await greenlet_spawn( + ^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 201, in greenlet_spawn + result = context.throw(*sys.exc_info()) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2421, in scalar + return self._execute_internal( + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2261, in _execute_internal + conn = self._connection_for_bind(bind) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2113, in _connection_for_bind + return trans._connection_for_bind(engine, execution_options) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "", line 2, in _connection_for_bind + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\state_changes.py", line 137, in _go + ret_value = fn(self, *arg, **kw) + ^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 1191, in _connection_for_bind + conn = bind.connect() + ^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 3295, in connect + return self._connection_cls(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 146, in __init__ + Connection._handle_dbapi_exception_noconnection( + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 2450, in _handle_dbapi_exception_noconnection + raise sqlalchemy_exception.with_traceback(exc_info[2]) from e + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 144, in __init__ + self._dbapi_connection = engine.raw_connection() + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 3319, in raw_connection + return self.pool.connect() + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 448, in connect + return _ConnectionFairy._checkout(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 1272, in _checkout + fairy = _ConnectionRecord.checkout(pool) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 712, in checkout + rec = pool._do_get() + ^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 178, in _do_get + with util.safe_reraise(): + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 122, in __exit__ + raise exc_value.with_traceback(exc_tb) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 176, in _do_get + return self._create_connection() + ^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 389, in _create_connection + return _ConnectionRecord(self) + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 674, in __init__ + self.__connect() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 900, in __connect + with util.safe_reraise(): + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 122, in __exit__ + raise exc_value.with_traceback(exc_tb) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 896, in __connect + self.dbapi_connection = connection = pool._invoke_creator(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\create.py", line 667, in connect + return dialect.connect(*cargs_tup, **cparams) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\default.py", line 630, in connect + return self.loaded_dbapi.connect(*cargs, **cparams) # type: ignore[no-any-return] # NOQA: E501 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\dialects\mysql\aiomysql.py", line 176, in connect + await_only(creator_fn(*arg, **kw)), + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 132, in await_only + return current.parent.switch(awaitable) # type: ignore[no-any-return,attr-defined] # noqa: E501 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 196, in greenlet_spawn + value = await result + ^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 74, in _connect + await conn._connect() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 540, in _connect + await self._request_authentication() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 865, in _request_authentication + await self.caching_sha2_password_auth(auth_packet) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 952, in caching_sha2_password_auth + pkt = await self._read_packet() + ^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 652, in _read_packet + packet.raise_for_error() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\pymysql\protocol.py", line 219, in raise_for_error + err.raise_mysql_exception(self._data) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\pymysql\err.py", line 154, in raise_mysql_exception + raise errorclass(errno, errval, sqlstate=sqlstate) +sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (1049, "Unknown database 'memory'") +(Background on this error at: https://sqlalche.me/e/20/e3q8) +2026-09-10 21:54:16,943 ERROR [-] api: unhandled error on /api/products +Traceback (most recent call last): + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 144, in __init__ + self._dbapi_connection = engine.raw_connection() + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 3319, in raw_connection + return self.pool.connect() + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 448, in connect + return _ConnectionFairy._checkout(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 1272, in _checkout + fairy = _ConnectionRecord.checkout(pool) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 712, in checkout + rec = pool._do_get() + ^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 178, in _do_get + with util.safe_reraise(): + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 122, in __exit__ + raise exc_value.with_traceback(exc_tb) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 176, in _do_get + return self._create_connection() + ^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 389, in _create_connection + return _ConnectionRecord(self) + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 674, in __init__ + self.__connect() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 900, in __connect + with util.safe_reraise(): + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 122, in __exit__ + raise exc_value.with_traceback(exc_tb) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 896, in __connect + self.dbapi_connection = connection = pool._invoke_creator(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\create.py", line 667, in connect + return dialect.connect(*cargs_tup, **cparams) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\default.py", line 630, in connect + return self.loaded_dbapi.connect(*cargs, **cparams) # type: ignore[no-any-return] # NOQA: E501 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\dialects\mysql\aiomysql.py", line 176, in connect + await_only(creator_fn(*arg, **kw)), + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 132, in await_only + return current.parent.switch(awaitable) # type: ignore[no-any-return,attr-defined] # noqa: E501 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 196, in greenlet_spawn + value = await result + ^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 74, in _connect + await conn._connect() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 540, in _connect + await self._request_authentication() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 865, in _request_authentication + await self.caching_sha2_password_auth(auth_packet) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 989, in caching_sha2_password_auth + pkt = await self._read_packet() + ^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 652, in _read_packet + packet.raise_for_error() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\pymysql\protocol.py", line 219, in raise_for_error + err.raise_mysql_exception(self._data) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\pymysql\err.py", line 154, in raise_mysql_exception + raise errorclass(errno, errval, sqlstate=sqlstate) +pymysql.err.OperationalError: (1045, "Access denied for user 'root'@'localhost' (using password: YES)") + +The above exception was the direct cause of the following exception: + +Traceback (most recent call last): + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__ + await self.app(scope, receive, _send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\base.py", line 193, in __call__ + response = await self.dispatch_func(request, call_next) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\utils\request_id.py", line 28, in dispatch + response: Response = await call_next(request) + ^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\base.py", line 168, in call_next + raise app_exc from app_exc.__cause__ or app_exc.__context__ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\base.py", line 144, in coro + await self.app(scope, receive_or_disconnect, send_no_error) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\middleware\exceptions.py", line 63, in __call__ + await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\middleware\asyncexitstack.py", line 18, in __call__ + await self.app(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\routing.py", line 670, in __call__ + await self.middleware_stack(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 2734, in app + await route.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1791, in _handle_selected + await route.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1780, in handle + await self.original_router.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 2789, in handle + await included_router._handle_selected(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1800, in _handle_selected + await original_route.handle(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 1279, in handle + await app(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 158, in app + await wrap_app_handling_exceptions(app, request)(scope, receive, send) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app + raise exc + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\starlette\_exception_handler.py", line 42, in wrapped_app + await app(scope, receive, sender) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 144, in app + response = await f(request) + ^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 706, in app + raw_response = await run_endpoint_function( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\fastapi\routing.py", line 352, in run_endpoint_function + return await dependant.call(**values) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\api\routers\product.py", line 26, in products + data = await list_products( + ^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\service\product.py", line 54, in list_products + items, total = await ProductRepo(db).search( + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\repositories\product.py", line 64, in search + items = list((await self.db.scalars(stmt)).all()) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\ext\asyncio\session.py", line 561, in scalars + result = await self.execute( + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\ext\asyncio\session.py", line 448, in execute + result = await greenlet_spawn( + ^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 201, in greenlet_spawn + result = context.throw(*sys.exc_info()) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2373, in execute + return self._execute_internal( + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2261, in _execute_internal + conn = self._connection_for_bind(bind) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 2113, in _connection_for_bind + return trans._connection_for_bind(engine, execution_options) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "", line 2, in _connection_for_bind + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\state_changes.py", line 137, in _go + ret_value = fn(self, *arg, **kw) + ^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\orm\session.py", line 1191, in _connection_for_bind + conn = bind.connect() + ^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 3295, in connect + return self._connection_cls(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 146, in __init__ + Connection._handle_dbapi_exception_noconnection( + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 2450, in _handle_dbapi_exception_noconnection + raise sqlalchemy_exception.with_traceback(exc_info[2]) from e + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 144, in __init__ + self._dbapi_connection = engine.raw_connection() + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\base.py", line 3319, in raw_connection + return self.pool.connect() + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 448, in connect + return _ConnectionFairy._checkout(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 1272, in _checkout + fairy = _ConnectionRecord.checkout(pool) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 712, in checkout + rec = pool._do_get() + ^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 178, in _do_get + with util.safe_reraise(): + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 122, in __exit__ + raise exc_value.with_traceback(exc_tb) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\impl.py", line 176, in _do_get + return self._create_connection() + ^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 389, in _create_connection + return _ConnectionRecord(self) + ^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 674, in __init__ + self.__connect() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 900, in __connect + with util.safe_reraise(): + ^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\langhelpers.py", line 122, in __exit__ + raise exc_value.with_traceback(exc_tb) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\pool\base.py", line 896, in __connect + self.dbapi_connection = connection = pool._invoke_creator(self) + ^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\create.py", line 667, in connect + return dialect.connect(*cargs_tup, **cparams) + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\engine\default.py", line 630, in connect + return self.loaded_dbapi.connect(*cargs, **cparams) # type: ignore[no-any-return] # NOQA: E501 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\dialects\mysql\aiomysql.py", line 176, in connect + await_only(creator_fn(*arg, **kw)), + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 132, in await_only + return current.parent.switch(awaitable) # type: ignore[no-any-return,attr-defined] # noqa: E501 + ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\sqlalchemy\util\_concurrency_py3k.py", line 196, in greenlet_spawn + value = await result + ^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 74, in _connect + await conn._connect() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 540, in _connect + await self._request_authentication() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 865, in _request_authentication + await self.caching_sha2_password_auth(auth_packet) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 989, in caching_sha2_password_auth + pkt = await self._read_packet() + ^^^^^^^^^^^^^^^^^^^^^^^^^ + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\aiomysql\connection.py", line 652, in _read_packet + packet.raise_for_error() + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\pymysql\protocol.py", line 219, in raise_for_error + err.raise_mysql_exception(self._data) + File "C:\Users\Windows\PycharmProjects\Mutual_Fund\.venv\Lib\site-packages\pymysql\err.py", line 154, in raise_mysql_exception + raise errorclass(errno, errval, sqlstate=sqlstate) +sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (1045, "Access denied for user 'root'@'localhost' (using password: YES)") +(Background on this error at: https://sqlalche.me/e/20/e3q8) diff --git a/repositories/sys_user.py b/repositories/sys_user.py index d8dc4a4..5304dc5 100644 --- a/repositories/sys_user.py +++ b/repositories/sys_user.py @@ -11,4 +11,7 @@ class SysUserRepo(BaseRepository): model = SysUser async def get_by_username(self, username: str) -> SysUser | None: - return await self.db.scalar(select(SysUser).where(SysUser.username == username)) \ No newline at end of file + return await self.db.scalar(select(SysUser).where(SysUser.username == username)) + + async def get_by_phone(self, phone: str) -> SysUser | None: + return await self.db.scalar(select(SysUser).where(SysUser.phone == phone)) \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 55494c7..0fc9de2 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,12 +1,10 @@ -fastapi -uvicorn -httpx -pyjwt -pydantic -pydantic-settings -sqlalchemy -aiomysql -redis -pymilvus -neo4j -python-dotenv \ No newline at end of file +fastapi~=0.141.1 +sqlalchemy~=2.0.52 +httpx~=0.28.1 +pydantic~=2.13.5 +starlette~=1.6.0 +neo4j~=6.3.0 +redis~=8.1.0 +pymilvus~=3.0.1 +pydantic-settings~=2.15.0 +pyjwt~=2.13.0 \ No newline at end of file diff --git a/schemas/auth.py b/schemas/auth.py index 0084476..6c8f08b 100644 --- a/schemas/auth.py +++ b/schemas/auth.py @@ -4,4 +4,11 @@ from pydantic import BaseModel, Field class LoginReq(BaseModel): username: str = Field(min_length=1, max_length=64) - password: str = Field(min_length=1, max_length=128) \ No newline at end of file + password: str = Field(min_length=1, max_length=128) + + +class RegisterReq(BaseModel): + username: str = Field(min_length=1, max_length=64) + password: str = Field(min_length=8, max_length=128, description="密码至少 8 位") + phone: str = Field(pattern=r"^1\d{10}$", description="11 位手机号") + real_name: str | None = Field(default=None, max_length=32) \ No newline at end of file diff --git a/service/auth.py b/service/auth.py index 3ca1a2e..2d47c7e 100644 --- a/service/auth.py +++ b/service/auth.py @@ -70,4 +70,30 @@ async def login(db: AsyncSession, username: str, password: str) -> dict: raise ParamError("用户名或密码错误") if user.status != "正常": raise ForbiddenError("账号状态异常,无法登录") - return {"token": create_token(user.id), "user": user_payload(user)} \ No newline at end of file + return {"token": create_token(user.id), "user": user_payload(user)} + + +async def register( + db: AsyncSession, + username: str, + password: str, + phone: str, + real_name: str | None = None, +) -> dict: + """客户注册:唯一性校验 → 密码加密存储 → 返回用户信息(不自动签发 token)。""" + repo = SysUserRepo(db) + if await repo.get_by_username(username) is not None: + raise ParamError("用户名已存在") + if await repo.get_by_phone(phone) is not None: + raise ParamError("手机号已注册") + + user = SysUser( + username=username, + password_hash=hash_password(password), + phone=phone, + real_name=real_name, + user_type="CUSTOMER", + status="正常", + ) + user = await repo.add(user) + return user_payload(user) \ No newline at end of file diff --git a/sql/schema.sql b/sql/schema.sql index f2d3f68..ac56327 100644 --- a/sql/schema.sql +++ b/sql/schema.sql @@ -59,7 +59,6 @@ CREATE TABLE IF NOT EXISTS fin_product ( expected_return DECIMAL(7,4) NULL COMMENT '预期年化收益率(%)', nav DECIMAL(12,6) NULL COMMENT '最新单位净值', nav_date DATE NULL COMMENT '净值日期', - min_amount DECIMAL(16,2) NOT NULL DEFAULT 10.00 COMMENT '起投金额(元)', fee_rate DECIMAL(6,4) NOT NULL DEFAULT 0.0000 COMMENT '申购费率(%)', term_days INT NOT NULL DEFAULT 0 COMMENT '产品期限天数,0=活期(开放申赎)', fund_manager VARCHAR(64) NULL COMMENT '基金经理', From 9cb07473034b015cc184f4066cd0b1528eafa0df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=AE=81=E5=AE=B6=E5=AF=85?= <15277360553@163.com> Date: Thu, 10 Sep 2026 23:19:25 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat:=E6=96=B0=E5=A2=9E=E5=9F=BA=E9=87=91?= =?UTF-8?q?=E4=BA=A7=E5=93=81=E5=88=97=E8=A1=A8=E6=8E=A5=E5=8F=A3,?= =?UTF-8?q?=E5=8E=86=E5=8F=B2=E4=B8=9A=E7=BB=A9=E6=8E=A5=E5=8F=A3,?= =?UTF-8?q?=E5=AE=A2=E6=88=B7=E6=B3=A8=E5=86=8C=E6=8F=90=E4=BA=A4=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3,=E9=97=AE=E5=8D=B7=E6=8F=90=E4=BA=A4=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/routers/product.py | 49 ++++++++++ api/routers/questionnaire.py | 23 +++++ model/fin_customer_profile.py | 32 +++++++ model/fin_product.py | 32 +++++++ model/fin_risk_assessment.py | 26 ++++++ model/fund_nav_history.py | 23 +++++ model/ops_question.py | 22 +++++ model/ops_questionnaire.py | 24 +++++ repositories/fund_nav.py | 32 +++++++ repositories/product.py | 71 +++++++++++++++ repositories/questionnaire.py | 24 +++++ repositories/risk_assessment.py | 46 ++++++++++ schemas/questionnaire.py | 12 +++ service/product.py | 155 ++++++++++++++++++++++++++++++++ service/questionnaire.py | 85 ++++++++++++++++++ 15 files changed, 656 insertions(+) create mode 100644 api/routers/product.py create mode 100644 api/routers/questionnaire.py create mode 100644 model/fin_customer_profile.py create mode 100644 model/fin_product.py create mode 100644 model/fin_risk_assessment.py create mode 100644 model/fund_nav_history.py create mode 100644 model/ops_question.py create mode 100644 model/ops_questionnaire.py create mode 100644 repositories/fund_nav.py create mode 100644 repositories/product.py create mode 100644 repositories/questionnaire.py create mode 100644 repositories/risk_assessment.py create mode 100644 schemas/questionnaire.py create mode 100644 service/product.py create mode 100644 service/questionnaire.py diff --git a/api/routers/product.py b/api/routers/product.py new file mode 100644 index 0000000..81928d2 --- /dev/null +++ b/api/routers/product.py @@ -0,0 +1,49 @@ +"""产品路由:列表 + 历史业绩(匿名可访问,业务在 service/product.py)。""" +from datetime import date + +from fastapi import APIRouter, Depends, Query +from sqlalchemy.ext.asyncio import AsyncSession + +from config.deps import get_db +from service.product import get_history, list_products +from utils.response import success + +router = APIRouter() + + +@router.get("/products") +async def products( + page: int = Query(1, ge=1), + page_size: int = Query(10, ge=1, le=100), + keyword: str | None = Query(None, max_length=64), + product_type: str | None = Query(None, max_length=32), + risk_level: str | None = Query(None, max_length=8), + status: str = Query("在售", max_length=16), + sort_by: str = Query("create_time", max_length=32), + sort_order: str = Query("desc", max_length=4), + db: AsyncSession = Depends(get_db), +): + data = await list_products( + db, + page=page, + page_size=page_size, + keyword=keyword, + product_type=product_type, + risk_level=risk_level, + status=status, + sort_by=sort_by, + sort_order=sort_order, + ) + return success(data) + + +@router.get("/products/{product_code}/history") +async def history( + product_code: str, + start_date: date | None = Query(None), + end_date: date | None = Query(None), + series: str = Query("nav", max_length=16), + db: AsyncSession = Depends(get_db), +): + data = await get_history(db, product_code, start_date, end_date, series) + return success(data) diff --git a/api/routers/questionnaire.py b/api/routers/questionnaire.py new file mode 100644 index 0000000..b62ad42 --- /dev/null +++ b/api/routers/questionnaire.py @@ -0,0 +1,23 @@ +"""问卷路由:风险测评提交(需登录,业务在 service/questionnaire.py)。""" +from fastapi import APIRouter, Depends +from sqlalchemy.ext.asyncio import AsyncSession + +from api.deps import get_current_user +from config.deps import get_db +from model.sys_user import SysUser +from schemas.questionnaire import RiskAssessmentSubmitReq +from service.questionnaire import submit_assessment +from utils.response import success + +router = APIRouter() + + +@router.post("/risk-assessment/submit") +async def submit( + body: RiskAssessmentSubmitReq, + user: SysUser = Depends(get_current_user), + db: AsyncSession = Depends(get_db), +): + answers = [a.model_dump() for a in body.answers] + data = await submit_assessment(db, user.id, body.questionnaire_id, answers) + return success(data) diff --git a/model/fin_customer_profile.py b/model/fin_customer_profile.py new file mode 100644 index 0000000..a9e8389 --- /dev/null +++ b/model/fin_customer_profile.py @@ -0,0 +1,32 @@ +"""fin_customer_profile 客户画像主表 ORM 模型。""" +from __future__ import annotations + +from datetime import datetime +from decimal import Decimal +from typing import Any + +from sqlalchemy import BigInteger, DateTime, Integer, JSON, Numeric, String, func +from sqlalchemy.orm import Mapped, mapped_column + +from model.base import Base + + +class FinCustomerProfile(Base): + __tablename__ = "fin_customer_profile" + __table_args__ = {"comment": "客户画像主表(RAG/GraphRAG 个性化推荐核心上下文)"} + + # 主键为 customer_id(一对一关联 sys_user.id),非自增 id + customer_id: Mapped[int] = mapped_column(BigInteger, primary_key=True) + risk_level: Mapped[str | None] = mapped_column(String(16)) + risk_score: Mapped[int | None] = mapped_column(Integer) + investment_experience: Mapped[str | None] = mapped_column(String(16)) + annual_income_range: Mapped[str | None] = mapped_column(String(32)) + total_assets: Mapped[Decimal | None] = mapped_column(Numeric(18, 2)) + asset_allocation: Mapped[dict[str, Any] | None] = mapped_column(JSON) + product_preference: Mapped[dict[str, Any] | None] = mapped_column(JSON) + customer_level: Mapped[str | None] = mapped_column(String(16)) + confidence_score: Mapped[Decimal] = mapped_column(Numeric(5, 2), server_default="0.50") + profile_version: Mapped[int] = mapped_column(Integer, server_default="1") + update_time: Mapped[datetime] = mapped_column( + DateTime, server_default=func.now(), onupdate=func.now() + ) diff --git a/model/fin_product.py b/model/fin_product.py new file mode 100644 index 0000000..f324ba9 --- /dev/null +++ b/model/fin_product.py @@ -0,0 +1,32 @@ +"""fin_product 公募基金产品表 ORM 模型。""" +from __future__ import annotations + +from datetime import date, datetime +from decimal import Decimal + +from sqlalchemy import BigInteger, Date, DateTime, Integer, Numeric, String, func +from sqlalchemy.orm import Mapped, mapped_column + +from model.base import Base + + +class FinProduct(Base): + __tablename__ = "fin_product" + __table_args__ = {"comment": "公募基金产品表"} + + id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) + product_code: Mapped[str] = mapped_column(String(32), unique=True) + product_name: Mapped[str] = mapped_column(String(128)) + product_type: Mapped[str] = mapped_column(String(32)) + risk_level: Mapped[str] = mapped_column(String(8)) + expected_return: Mapped[Decimal | None] = mapped_column(Numeric(7, 4)) + nav: Mapped[Decimal | None] = mapped_column(Numeric(12, 6)) + nav_date: Mapped[date | None] = mapped_column(Date) + fee_rate: Mapped[Decimal] = mapped_column(Numeric(6, 4), server_default="0.0000") + term_days: Mapped[int] = mapped_column(Integer, server_default="0") + fund_manager: Mapped[str | None] = mapped_column(String(64)) + status: Mapped[str] = mapped_column(String(16), server_default="在售") + create_time: Mapped[datetime] = mapped_column(DateTime, server_default=func.now()) + update_time: Mapped[datetime] = mapped_column( + DateTime, server_default=func.now(), onupdate=func.now() + ) diff --git a/model/fin_risk_assessment.py b/model/fin_risk_assessment.py new file mode 100644 index 0000000..f9995ba --- /dev/null +++ b/model/fin_risk_assessment.py @@ -0,0 +1,26 @@ +"""fin_risk_assessment 风险评估记录表 ORM 模型。""" +from __future__ import annotations + +from datetime import date, datetime +from typing import Any + +from sqlalchemy import BigInteger, Date, DateTime, Integer, JSON, String, func +from sqlalchemy.orm import Mapped, mapped_column + +from model.base import Base + + +class FinRiskAssessment(Base): + __tablename__ = "fin_risk_assessment" + __table_args__ = {"comment": "风险评估记录表(购买前问卷确认客户等级)"} + + id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) + customer_id: Mapped[int] = mapped_column(BigInteger) + assessment_date: Mapped[date] = mapped_column(Date) + question_version: Mapped[str | None] = mapped_column(String(16)) + total_score: Mapped[int] = mapped_column(Integer) + risk_level: Mapped[str] = mapped_column(String(16)) + answers: Mapped[list[Any] | None] = mapped_column(JSON) + assessor_type: Mapped[str] = mapped_column(String(16), server_default="AI评估") + valid_until: Mapped[date] = mapped_column(Date) + create_time: Mapped[datetime] = mapped_column(DateTime, server_default=func.now()) diff --git a/model/fund_nav_history.py b/model/fund_nav_history.py new file mode 100644 index 0000000..f05dcbc --- /dev/null +++ b/model/fund_nav_history.py @@ -0,0 +1,23 @@ +"""fund_nav_history 基金净值历史表 ORM 模型。""" +from __future__ import annotations + +from datetime import date, datetime +from decimal import Decimal + +from sqlalchemy import BigInteger, Date, DateTime, Numeric, func +from sqlalchemy.orm import Mapped, mapped_column + +from model.base import Base + + +class FundNavHistory(Base): + __tablename__ = "fund_nav_history" + __table_args__ = {"comment": "基金净值历史(业绩指标/走势图数据源)"} + + id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) + product_id: Mapped[int] = mapped_column(BigInteger) + nav_date: Mapped[date] = mapped_column(Date) + unit_nav: Mapped[Decimal] = mapped_column(Numeric(12, 6)) + accumulated_nav: Mapped[Decimal | None] = mapped_column(Numeric(12, 6)) + daily_growth: Mapped[Decimal | None] = mapped_column(Numeric(8, 4)) + create_time: Mapped[datetime] = mapped_column(DateTime, server_default=func.now()) diff --git a/model/ops_question.py b/model/ops_question.py new file mode 100644 index 0000000..d7cd249 --- /dev/null +++ b/model/ops_question.py @@ -0,0 +1,22 @@ +"""ops_question 问卷题目表 ORM 模型。""" +from __future__ import annotations + +from typing import Any + +from sqlalchemy import BigInteger, Integer, JSON, String +from sqlalchemy.orm import Mapped, mapped_column + +from model.base import Base + + +class OpsQuestion(Base): + __tablename__ = "ops_question" + __table_args__ = {"comment": "问卷题目表(题目/选项/分值可运营配置)"} + + id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) + questionnaire_id: Mapped[int] = mapped_column(BigInteger) + question_no: Mapped[int] = mapped_column(Integer) + content: Mapped[str] = mapped_column(String(512)) + option_json: Mapped[list[Any] | None] = mapped_column(JSON) + score_json: Mapped[dict[str, Any] | None] = mapped_column(JSON) + sort: Mapped[int] = mapped_column(Integer, server_default="0") diff --git a/model/ops_questionnaire.py b/model/ops_questionnaire.py new file mode 100644 index 0000000..05bc560 --- /dev/null +++ b/model/ops_questionnaire.py @@ -0,0 +1,24 @@ +"""ops_questionnaire 问卷模板表 ORM 模型。""" +from __future__ import annotations + +from datetime import datetime + +from sqlalchemy import BigInteger, DateTime, String, func +from sqlalchemy.orm import Mapped, mapped_column + +from model.base import Base + + +class OpsQuestionnaire(Base): + __tablename__ = "ops_questionnaire" + __table_args__ = {"comment": "问卷模板表"} + + id: Mapped[int] = mapped_column(BigInteger, primary_key=True, autoincrement=True) + name: Mapped[str] = mapped_column(String(64)) + q_type: Mapped[str] = mapped_column(String(16)) + version: Mapped[str] = mapped_column(String(16), server_default="v1") + status: Mapped[str] = mapped_column(String(16), server_default="启用") + create_time: Mapped[datetime] = mapped_column(DateTime, server_default=func.now()) + update_time: Mapped[datetime] = mapped_column( + DateTime, server_default=func.now(), onupdate=func.now() + ) diff --git a/repositories/fund_nav.py b/repositories/fund_nav.py new file mode 100644 index 0000000..6d58e8f --- /dev/null +++ b/repositories/fund_nav.py @@ -0,0 +1,32 @@ +"""fund_nav_history 净值历史仓储:按产品代码与日期区间查询走势。 + +数据现状说明:fund_nav_history.product_id 列在 Mock 数据灌入时存的是基金代码 +(如 110001)而非 fin_product 主键 id。为不改数据库、只通过代码适配,这里用 +CAST 把 BIGINT 列按字符串与 product_code 比对。 +""" +from __future__ import annotations + +from datetime import date + +from sqlalchemy import String, cast, select + +from model.fund_nav_history import FundNavHistory +from repositories.base import BaseRepository + + +class FundNavRepo(BaseRepository): + model = FundNavHistory + + async def list_series( + self, product_code: str, start_date: date, end_date: date + ) -> list[FundNavHistory]: + stmt = ( + select(FundNavHistory) + .where( + cast(FundNavHistory.product_id, String) == product_code, + FundNavHistory.nav_date >= start_date, + FundNavHistory.nav_date <= end_date, + ) + .order_by(FundNavHistory.nav_date.asc()) + ) + return list((await self.db.scalars(stmt)).all()) diff --git a/repositories/product.py b/repositories/product.py new file mode 100644 index 0000000..2eddc99 --- /dev/null +++ b/repositories/product.py @@ -0,0 +1,71 @@ +"""fin_product 产品仓储:列表搜索(关键字/类型/风险/状态筛选 + 排序 + 分页)。""" +from __future__ import annotations + +from sqlalchemy import or_, select + +from model.fin_product import FinProduct +from repositories.base import BaseRepository +from utils.exceptions import ParamError + +# 排序字段白名单:防止 sort_by 注入,字符串映射到 ORM 列(不拼 SQL) +SORTABLE_FIELDS = { + "expected_return": FinProduct.expected_return, + "nav": FinProduct.nav, + "fee_rate": FinProduct.fee_rate, + "risk_level": FinProduct.risk_level, + "create_time": FinProduct.create_time, +} + + +class ProductRepo(BaseRepository): + model = FinProduct + + async def get_by_code(self, product_code: str) -> FinProduct | None: + return await self.db.scalar( + select(FinProduct).where(FinProduct.product_code == product_code) + ) + + async def search( + self, + *, + keyword: str | None = None, + product_type: str | None = None, + risk_level: str | None = None, + status: str | None = "在售", + sort_by: str = "create_time", + sort_order: str = "desc", + limit: int = 10, + offset: int = 0, + ) -> tuple[list[FinProduct], int]: + conds = [] + if status and status != "全部": + conds.append(FinProduct.status == status) + if product_type: + conds.append(FinProduct.product_type == product_type) + if risk_level: + conds.append(FinProduct.risk_level == risk_level) + if keyword: + like = f"%{keyword}%" + conds.append( + or_( + FinProduct.product_code.like(like), + FinProduct.product_name.like(like), + FinProduct.fund_manager.like(like), + ) + ) + + col = SORTABLE_FIELDS.get(sort_by) + if col is None: + raise ParamError(f"不支持的排序字段: {sort_by}") + order_col = col.desc() if sort_order == "desc" else col.asc() + + stmt = ( + select(FinProduct) + .where(*conds) + .order_by(order_col) + .limit(limit) + .offset(offset) + ) + items = list((await self.db.scalars(stmt)).all()) + total = await self.count(where=conds) + return items, total diff --git a/repositories/questionnaire.py b/repositories/questionnaire.py new file mode 100644 index 0000000..b459b3f --- /dev/null +++ b/repositories/questionnaire.py @@ -0,0 +1,24 @@ +"""问卷域仓储:问卷模板 + 题目。""" +from __future__ import annotations + +from sqlalchemy import select + +from model.ops_question import OpsQuestion +from model.ops_questionnaire import OpsQuestionnaire +from repositories.base import BaseRepository + + +class QuestionnaireRepo(BaseRepository): + model = OpsQuestionnaire + + +class QuestionRepo(BaseRepository): + model = OpsQuestion + + async def list_by_questionnaire(self, questionnaire_id: int) -> list[OpsQuestion]: + stmt = ( + select(OpsQuestion) + .where(OpsQuestion.questionnaire_id == questionnaire_id) + .order_by(OpsQuestion.question_no.asc(), OpsQuestion.sort.asc()) + ) + return list((await self.db.scalars(stmt)).all()) diff --git a/repositories/risk_assessment.py b/repositories/risk_assessment.py new file mode 100644 index 0000000..20b0ced --- /dev/null +++ b/repositories/risk_assessment.py @@ -0,0 +1,46 @@ +"""风评域仓储:风评记录 + 客户画像(画像主键为 customer_id)。""" +from __future__ import annotations + +from sqlalchemy import select + +from model.fin_customer_profile import FinCustomerProfile +from model.fin_risk_assessment import FinRiskAssessment +from repositories.base import BaseRepository + + +class RiskAssessmentRepo(BaseRepository): + model = FinRiskAssessment + + +class CustomerProfileRepo(BaseRepository): + """客户画像仓储。注意:主键是 customer_id 而非 id,不适用基类 get(pk)。""" + + model = FinCustomerProfile + + async def get_by_customer(self, customer_id: int) -> FinCustomerProfile | None: + return await self.db.scalar( + select(FinCustomerProfile).where( + FinCustomerProfile.customer_id == customer_id + ) + ) + + async def upsert_risk( + self, customer_id: int, risk_level: str, risk_score: int + ) -> FinCustomerProfile: + """回写风险等级与评分:无画像则初始化,有则更新并递增画像版本号。""" + profile = await self.get_by_customer(customer_id) + if profile is None: + profile = FinCustomerProfile( + customer_id=customer_id, + risk_level=risk_level, + risk_score=risk_score, + profile_version=1, + ) + self.db.add(profile) + else: + profile.risk_level = risk_level + profile.risk_score = risk_score + profile.profile_version = (profile.profile_version or 0) + 1 + await self.db.commit() + await self.db.refresh(profile) + return profile diff --git a/schemas/questionnaire.py b/schemas/questionnaire.py new file mode 100644 index 0000000..7b0da7d --- /dev/null +++ b/schemas/questionnaire.py @@ -0,0 +1,12 @@ +"""问卷提交相关 DTO。""" +from pydantic import BaseModel, Field + + +class AnswerItem(BaseModel): + question_no: int = Field(gt=0) + option: str = Field(min_length=1, max_length=8) + + +class RiskAssessmentSubmitReq(BaseModel): + questionnaire_id: int = Field(gt=0) + answers: list[AnswerItem] = Field(min_length=1) diff --git a/service/product.py b/service/product.py new file mode 100644 index 0000000..0bb05b4 --- /dev/null +++ b/service/product.py @@ -0,0 +1,155 @@ +"""产品服务:列表(分页/筛选/排序)+ 历史业绩(净值/收益走势)。""" +from __future__ import annotations + +from datetime import date, timedelta + +from sqlalchemy.ext.asyncio import AsyncSession + +from model.fin_product import FinProduct +from repositories.fund_nav import FundNavRepo +from repositories.product import ProductRepo +from utils.exceptions import NotFoundError, ParamError + + +def _to_item(p: FinProduct) -> dict: + """ORM → 响应 dict(Decimal 显式转 float,避免序列化歧义)。""" + return { + "id": p.id, + "product_code": p.product_code, + "product_name": p.product_name, + "product_type": p.product_type, + "risk_level": p.risk_level, + "expected_return": float(p.expected_return) if p.expected_return is not None else None, + "nav": float(p.nav) if p.nav is not None else None, + "nav_date": p.nav_date.isoformat() if p.nav_date else None, + "fee_rate": float(p.fee_rate), + "term_days": p.term_days, + "fund_manager": p.fund_manager, + "status": p.status, + # 不改表:交易方式标识由现有字段推导(status=在售 可购买;term_days=0 可定投) + "support_purchase": p.status == "在售", + "support_dca": p.term_days == 0, + } + + +async def list_products( + db: AsyncSession, + *, + page: int = 1, + page_size: int = 10, + keyword: str | None = None, + product_type: str | None = None, + risk_level: str | None = None, + status: str = "在售", + sort_by: str = "create_time", + sort_order: str = "desc", +) -> dict: + if page < 1: + raise ParamError("page 必须 >= 1") + if page_size < 1 or page_size > 100: + raise ParamError("page_size 必须在 1-100 之间") + if sort_order not in ("asc", "desc"): + raise ParamError("sort_order 仅支持 asc/desc") + + items, total = await ProductRepo(db).search( + keyword=keyword, + product_type=product_type, + risk_level=risk_level, + status=status, + sort_by=sort_by, + sort_order=sort_order, + limit=page_size, + offset=(page - 1) * page_size, + ) + return { + "total": total, + "page": page, + "page_size": page_size, + "items": [_to_item(p) for p in items], + } + + +def _calc_metrics(rows: list) -> dict: + """基于净值序列计算区间汇总指标(百分比)。 + + - total_growth_rate:总增长率 = 每天日增长率累加 + - max_return_rate:区间最大收益率 = 从区间内最低点买入到其后最高点的最大涨幅 + - max_drawdown_rate:区间最大回撤率 = 从区间内最高点回落到其后最低点的最大跌幅 + """ + total_growth = sum( + float(r.daily_growth) for r in rows if r.daily_growth is not None + ) + + peak = trough = float(rows[0].unit_nav) + max_return = max_drawdown = 0.0 + for r in rows: + nav = float(r.unit_nav) + peak = max(peak, nav) + trough = min(trough, nav) + max_drawdown = max(max_drawdown, (peak - nav) / peak if peak else 0.0) + max_return = max(max_return, (nav - trough) / trough if trough else 0.0) + + return { + "total_growth_rate": round(total_growth, 4), + "max_return_rate": round(max_return * 100, 4), + "max_drawdown_rate": round(max_drawdown * 100, 4), + } + + +async def get_history( + db: AsyncSession, + product_code: str, + start_date: date | None = None, + end_date: date | None = None, + series: str = "nav", +) -> dict: + if series not in ("nav", "return"): + raise ParamError("series 仅支持 nav/return") + if await ProductRepo(db).get_by_code(product_code) is None: + raise NotFoundError("基金产品不存在") + + end = end_date or date.today() + start = start_date or (end - timedelta(days=90)) + if start > end: + raise ParamError("start_date 不能晚于 end_date") + + rows = await FundNavRepo(db).list_series(product_code, start, end) + if not rows: + return { + "product_code": product_code, + "series": series, + "total_growth_rate": 0.0, + "max_return_rate": 0.0, + "max_drawdown_rate": 0.0, + "items": [], + } + + if series == "nav": + items = [ + { + "nav_date": r.nav_date.isoformat(), + "unit_nav": float(r.unit_nav), + "accumulated_nav": float(r.accumulated_nav) if r.accumulated_nav is not None else None, + "daily_growth": float(r.daily_growth) if r.daily_growth is not None else None, + } + for r in rows + ] + else: + base = float(rows[0].unit_nav) # 区间首日为基准,累计收益实时从净值计算 + items = [ + { + "nav_date": r.nav_date.isoformat(), + "unit_nav": float(r.unit_nav), + "cum_return_pct": round((float(r.unit_nav) / base - 1) * 100, 4), + } + for r in rows + ] + metrics = _calc_metrics(rows) + return { + "product_code": product_code, + "series": series, + "total_growth_rate": metrics["total_growth_rate"], + "max_return_rate": metrics["max_return_rate"], + "max_drawdown_rate": metrics["max_drawdown_rate"], + "items": items, + } diff --git a/service/questionnaire.py b/service/questionnaire.py new file mode 100644 index 0000000..e1ec9e5 --- /dev/null +++ b/service/questionnaire.py @@ -0,0 +1,85 @@ +"""问卷服务:提交风险测评 → 完整性/选项校验 → 算分定级 → 落风评记录 → 回写画像。""" +from __future__ import annotations + +from datetime import date, timedelta + +from sqlalchemy.ext.asyncio import AsyncSession + +from model.fin_risk_assessment import FinRiskAssessment +from repositories.questionnaire import QuestionRepo, QuestionnaireRepo +from repositories.risk_assessment import CustomerProfileRepo, RiskAssessmentRepo +from utils.exceptions import NotFoundError, ParamError + +# 分数 → 风险等级映射(总分 0-100,20 分一档;后续可迁移到 sys_config 运营化) +_SCORE_LEVELS = ( + (80, "激进"), + (60, "进取"), + (40, "平衡"), + (20, "稳健"), + (0, "保守"), +) + + +def _score_to_level(score: int) -> str: + for threshold, level in _SCORE_LEVELS: + if score >= threshold: + return level + return "保守" + + +async def submit_assessment( + db: AsyncSession, + customer_id: int, + questionnaire_id: int, + answers: list[dict], +) -> dict: + questionnaire = await QuestionnaireRepo(db).get(questionnaire_id) + if questionnaire is None: + raise NotFoundError("问卷不存在") + if questionnaire.status != "启用": + raise ParamError("问卷未启用") + + questions = await QuestionRepo(db).list_by_questionnaire(questionnaire_id) + if not questions: + raise ParamError("问卷尚未配置题目") + + # 提交答案按 question_no(题号)建索引,校验必填完整性与选项合法性 + by_no = {a["question_no"]: a["option"] for a in answers} + total_score = 0 + detail = [] + for q in questions: + option = by_no.get(q.question_no) + if option is None: + raise ParamError(f"第{q.question_no}题未作答") + scores = q.score_json or {} + if option not in scores: + raise ParamError(f"第{q.question_no}题选项非法: {option}") + score = int(scores[option]) + total_score += score + detail.append({"q": q.question_no, "a": option, "score": score}) + + risk_level = _score_to_level(total_score) + today = date.today() + valid_until = today + timedelta(days=365) # 监管要求一年一评 + + record = FinRiskAssessment( + customer_id=customer_id, + assessment_date=today, + question_version=questionnaire.version, + total_score=total_score, + risk_level=risk_level, + answers=detail, + assessor_type="AI评估", + valid_until=valid_until, + ) + record = await RiskAssessmentRepo(db).add(record) + + # 回写画像:无画像初始化,有画像更新风险等级/评分并递增版本号 + await CustomerProfileRepo(db).upsert_risk(customer_id, risk_level, total_score) + + return { + "assessment_id": record.id, + "total_score": total_score, + "risk_level": risk_level, + "valid_until": valid_until.isoformat(), + }