awtkns / fastapi-crudrouter

A dynamic FastAPI router that automatically creates CRUD routes for your models
https://fastapi-crudrouter.awtkns.com
MIT License
1.37k stars 154 forks source link

value is not a valid dict #197

Open LeiYangGH opened 1 month ago

LeiYangGH commented 1 month ago

This project is very useful and I want to use it in production, thanks a lot! I have tried the basic In Memory demo and works just as expected.

But when first try with mysql database, validation errors occurred.

I have searched and only found one closed issue with such error message. but my case is much simpler(if not simplest) and my model has only one field: the auto increase integer primary key.

code is like below

engine = create_engine(
    'my sql connection string'
)

SessionLocal = sessionmaker(
    autocommit=False,
    autoflush=False,
    bind=engine
)

Base = declarative_base()

def get_db():
    session = SessionLocal()
    try:
        yield session
        session.commit()
    finally:
        session.close()

class Video(BaseModel):
    id: int

class VideoModel(Base):
    __tablename__ = 'video'
    id = Column(Integer, primary_key=True, index=True)

Base.metadata.create_all(bind=engine)

video_router = SQLAlchemyCRUDRouter(
    schema=Video,
    db_model=VideoModel,
    db=get_db,
    prefix='video'
)

log

INFO:     Application startup complete.
INFO:     127.0.0.1:61628 - "GET /fapi/video HTTP/1.1" 500 Internal Server Error
ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "C:\a3\envs\fapi\Lib\site-packages\uvicorn\protocols\http\httptools_impl.py", line 399, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\a3\envs\fapi\Lib\site-packages\uvicorn\middleware\proxy_headers.py", line 70, in __call__
    return await self.app(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\a3\envs\fapi\Lib\site-packages\fastapi\applications.py", line 1054, in __call__
    await super().__call__(scope, receive, send)
  File "C:\a3\envs\fapi\Lib\site-packages\starlette\applications.py", line 123, in __call__
    await self.middleware_stack(scope, receive, send)
  File "C:\a3\envs\fapi\Lib\site-packages\starlette\middleware\errors.py", line 186, in __call__
    raise exc
  File "C:\a3\envs\fapi\Lib\site-packages\starlette\middleware\errors.py", line 164, in __call__
    await self.app(scope, receive, _send)
  File "C:\a3\envs\fapi\Lib\site-packages\starlette\middleware\exceptions.py", line 65, in __call__
    await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
  File "C:\a3\envs\fapi\Lib\site-packages\starlette\_exception_handler.py", line 64, in wrapped_app
    raise exc
  File "C:\a3\envs\fapi\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
    await app(scope, receive, sender)
  File "C:\a3\envs\fapi\Lib\site-packages\starlette\routing.py", line 756, in __call__
    await self.middleware_stack(scope, receive, send)
  File "C:\a3\envs\fapi\Lib\site-packages\starlette\routing.py", line 776, in app
    await route.handle(scope, receive, send)
  File "C:\a3\envs\fapi\Lib\site-packages\starlette\routing.py", line 297, in handle
    await self.app(scope, receive, send)
  File "C:\a3\envs\fapi\Lib\site-packages\starlette\routing.py", line 77, in app
    await wrap_app_handling_exceptions(app, request)(scope, receive, send)
  File "C:\a3\envs\fapi\Lib\site-packages\starlette\_exception_handler.py", line 64, in wrapped_app
    raise exc
  File "C:\a3\envs\fapi\Lib\site-packages\starlette\_exception_handler.py", line 53, in wrapped_app
    await app(scope, receive, sender)
  File "C:\a3\envs\fapi\Lib\site-packages\starlette\routing.py", line 72, in app
    response = await func(request)
               ^^^^^^^^^^^^^^^^^^^
  File "C:\a3\envs\fapi\Lib\site-packages\fastapi\routing.py", line 296, in app
    content = await serialize_response(
              ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\a3\envs\fapi\Lib\site-packages\fastapi\routing.py", line 155, in serialize_response
    raise ResponseValidationError(
fastapi.exceptions.ResponseValidationError: 10 validation errors:
  {'loc': ('response', 0), 'msg': 'value is not a valid dict', 'type': 'type_error.dict'}
  {'loc': ('response', 1), 'msg': 'value is not a valid dict', 'type': 'type_error.dict'}
  {'loc': ('response', 2), 'msg': 'value is not a valid dict', 'type': 'type_error.dict'}
  {'loc': ('response', 3), 'msg': 'value is not a valid dict', 'type': 'type_error.dict'}
  {'loc': ('response', 4), 'msg': 'value is not a valid dict', 'type': 'type_error.dict'}
  {'loc': ('response', 5), 'msg': 'value is not a valid dict', 'type': 'type_error.dict'}
  {'loc': ('response', 6), 'msg': 'value is not a valid dict', 'type': 'type_error.dict'}
  {'loc': ('response', 7), 'msg': 'value is not a valid dict', 'type': 'type_error.dict'}
  {'loc': ('response', 8), 'msg': 'value is not a valid dict', 'type': 'type_error.dict'}
  {'loc': ('response', 9), 'msg': 'value is not a valid dict', 'type': 'type_error.dict'}

pip freeze

annotated-types==0.7.0 anyio==3.7.1 certifi==2024.7.4 click==8.1.7 colorama==0.4.6 dnspython==2.6.1 email_validator==2.2.0 fastapi==0.111.1 fastapi-cli==0.0.4 fastapi-crudrouter==0.8.6 greenlet==3.0.3 h11==0.14.0 httpcore==1.0.5 httptools==0.6.1 httpx==0.27.0 idna==3.7 Jinja2==3.1.4 markdown-it-py==3.0.0 MarkupSafe==2.1.5 mdurl==0.1.2 mysqlclient==2.2.4 pydantic==1.10.17 pydantic_core==2.0.1 Pygments==2.18.0 python-dotenv==1.0.1 python-multipart==0.0.9 PyYAML==6.0.1 rich==13.7.1 shellingham==1.5.4 sniffio==1.3.1 SQLAlchemy==2.0.31 starlette==0.37.2 typer==0.12.3 typing_extensions==4.12.2 uvicorn==0.30.4 watchfiles==0.22.0 websockets==12.0

python version

(fapi) D:\G\fapi>python --version Python 3.11.9

system

win 11

note I must use pydantic==1.* due to other issues. Tried downgrade fastapi, pydantic, SQLAlchemy but none of them fixed such error, or cause more other errors.

LeiYangGH commented 1 month ago

update

searched and found one stackoverflow answer and solved with

    class Config:
        orm_mode = True

but the fastapi-crudrouter doc explains nothing on this topic. Could fastapi-crudrouter doc be updated to

  1. explain the reason
  2. possibly configure the orm_mode globally and not in every BaseModel?
  3. or even fixed with the library itself?