fastapi-users / fastapi-users

Ready-to-use and customizable users management for FastAPI
https://fastapi-users.github.io/fastapi-users/
MIT License
4.51k stars 383 forks source link

TypeError: 'Record' object is not a mapping #746

Closed Briscoooe closed 2 years ago

Briscoooe commented 2 years ago

Discussed in https://github.com/fastapi-users/fastapi-users/discussions/745

Originally posted by **Briscoooe** September 27, 2021 I am following [this example](https://replit.com/@frankie567/fastapi-users-sqlalchemy) in my project and I can't seem to get it to work. The error I am getting is ```Traceback (most recent call last): File "/usr/local/lib/python3.7/site-packages/uvicorn/protocols/http/httptools_impl.py", line 390, in run_asgi result = await app(self.scope, self.receive, self.send) File "/usr/local/lib/python3.7/site-packages/uvicorn/middleware/proxy_headers.py", line 45, in __call__ return await self.app(scope, receive, send) File "/usr/local/lib/python3.7/site-packages/fastapi/applications.py", line 199, in __call__ await super().__call__(scope, receive, send) File "/usr/local/lib/python3.7/site-packages/starlette/applications.py", line 112, in __call__ await self.middleware_stack(scope, receive, send) File "/usr/local/lib/python3.7/site-packages/starlette/middleware/errors.py", line 181, in __call__ raise exc from None File "/usr/local/lib/python3.7/site-packages/starlette/middleware/errors.py", line 159, in __call__ await self.app(scope, receive, _send) File "/usr/local/lib/python3.7/site-packages/starlette/middleware/cors.py", line 78, in __call__ await self.app(scope, receive, send) File "/usr/local/lib/python3.7/site-packages/starlette/exceptions.py", line 82, in __call__ raise exc from None File "/usr/local/lib/python3.7/site-packages/starlette/exceptions.py", line 71, in __call__ await self.app(scope, receive, sender) File "/usr/local/lib/python3.7/site-packages/starlette/routing.py", line 580, in __call__ await route.handle(scope, receive, send) File "/usr/local/lib/python3.7/site-packages/starlette/routing.py", line 241, in handle await self.app(scope, receive, send) File "/usr/local/lib/python3.7/site-packages/starlette/routing.py", line 52, in app response = await func(request) File "/usr/local/lib/python3.7/site-packages/fastapi/routing.py", line 217, in app dependant=dependant, values=values, is_coroutine=is_coroutine File "/usr/local/lib/python3.7/site-packages/fastapi/routing.py", line 149, in run_endpoint_function return await dependant.call(**values) File "/usr/local/lib/python3.7/site-packages/fastapi_users/router/auth.py", line 28, in login user = await user_manager.authenticate(credentials) File "/usr/local/lib/python3.7/site-packages/fastapi_users/manager.py", line 518, in authenticate user = await self.get_by_email(credentials.username) File "/usr/local/lib/python3.7/site-packages/fastapi_users/manager.py", line 102, in get_by_email user = await self.user_db.get_by_email(user_email) File "/usr/local/lib/python3.7/site-packages/fastapi_users_db_sqlalchemy/__init__.py", line 133, in get_by_email return await self._make_user(user) if user else None File "/usr/local/lib/python3.7/site-packages/fastapi_users_db_sqlalchemy/__init__.py", line 200, in _make_user user_dict = {**user} TypeError: 'Record' object is not a mapping ``` The request I am trying is [login](https://fastapi-users.github.io/fastapi-users/usage/routes/#post-login). I know the request is working up until the last point because when I try to login with a bad password I get a 400 error response with a JSON body. When I try and login with correct credentials (or even when the email does exist) I get a 500 as the user table record can't be mapped to the response body. I have followed the example to the letter, most of the code I have is copied 1:1 from the documentation so I can't really see why it doesn't work. Here are my tables and models. I have moved all the snippets to one block for brevity, in the project they all exist in separate files. ``` class User(Base, SQLAlchemyBaseUserTable): __tablename__ = 'user_' first_name = Column(String, nullable=False) last_name = Column(String, nullable=False) class User(models.BaseUser): pass class UserCreate(models.BaseUserCreate): pass class UserUpdate(models.BaseUserUpdate): pass class UserInDB(User, models.BaseUserDB): pass def get_user_db(): yield SQLAlchemyUserDatabase(UserInDB, database, User.__table__) SECRET = "SECRET" class UserManager(BaseUserManager[UserCreate, UserInDB]): user_db_model = UserInDB reset_password_token_secret = SECRET verification_token_secret = SECRET def get_user_manager(user_db: SQLAlchemyUserDatabase = Depends(deps.get_user_db)): yield UserManager(user_db) jwt_authentication = JWTAuthentication( secret=SECRET, lifetime_seconds=3600, tokenUrl="auth/jwt/login" ) fastapi_users = FastAPIUsers( get_user_manager, [jwt_authentication], User, UserCreate, UserUpdate, UserInDB, ) current_active_user = fastapi_users.current_user(active=True) api_router.include_router(users.fastapi_users.get_auth_router(users.jwt_authentication), prefix="/auth/jwt", tags=["auth"]) api_router.include_router(users.fastapi_users.get_register_router(), prefix="/auth", tags=["auth"]) api_router.include_router(users.fastapi_users.get_reset_password_router(), prefix="/auth", tags=["auth"]) api_router.include_router(users.fastapi_users.get_verify_router(), prefix="/auth", tags=["auth"]) api_router.include_router(users.fastapi_users.get_users_router(), prefix="/users", tags=["users"]) ```
Briscoooe commented 2 years ago

Closing this.

The issue was to do with the Base class I was passing into the User class, I was a different one which I already had in my code, rather than the DeclarativeMeta = declarative_base() one.