在FastAPI sqlachemy中连接2个表返回查询对象/

问题描述 投票:0回答:1

我正在从 YouTube 学习 FastAPI,当我们使用 sqlalchemy 连接表时,我没有得到与视频相同的结果。该视频是 2 年前的,我试图找到解决方案,但一无所获。

所以我尝试将

POST
表与
Vote
表以及每个帖子的投票计数连接起来,但我得到了总投票数,但没有得到帖子对象,它只是显示查询对象。

提前谢谢您。

型号

class Post(Base):
    __tablename__ = "posts"

    id = Column(Integer, primary_key=True, nullable=False)
    title = Column(String, nullable=False)
    content = Column(String, nullable=False)
    published = Column(Boolean, server_default="TRUE")
    created_at = Column(TIMESTAMP(timezone=True),
                        nullable=False, server_default=text('now()'))
    owner_id = Column(Integer, ForeignKey(
        "users.id", ondelete="CASCADE"), nullable=False)

    owner = relationship("User")


class Vote(Base):
    __tablename__ = "votes"

    user_id = Column(Integer, ForeignKey("users.id", ondelete="CASCADE"), primary_key=True)
    post_id = Column(Integer, ForeignKey("posts.id", ondelete="CASCADE"), primary_key=True)
    created_at = Column(TIMESTAMP(timezone=True),
                        nullable=False, server_default=text('now()'))

这是我的 POST 路由功能。给出查询对象的查询是结果

@router.get("/posts")
async def get_posts(
        db: Session = Depends(get_db),
        current_user: int = Depends(oauth2.get_current_user),
        search: Optional[str] = '',
):

    posts = db.query(models.Post).filter(models.Post.title.contains(search)).all()


    results = db.query(models.Post, func.count(models.Vote.post_id).label("votes_count")).\
join(models.Vote, models.Vote.post_id == models.Post.id, isouter=True).\
group_by(models.Post.id).all()

print(results)


    return results

“results”变量的打印输出:

[(<app.models.Post object at 0x7f19893fe310>, 0), (<app.models.Post object at 0x7f19893fe390>, 0), (<app.models.Post object at 0x7f19893fe210>, 1), (<app.models.Post object at 0x7f19893fe290>, 0), (<app.models.Post object at 0x7f19893fe410>, 0)]

我希望它位于实际的 POST 对象而不是查询对象中

返回结果时出现错误

INFO:     127.0.0.1:50202 - "GET /posts HTTP/1.1" 500 Internal Server Error
ERROR:    Exception in ASGI application
Traceback (most recent call last):
  File "/home/eminent/Documents/My codes/FastAPI/Tutorials/SocialAPI/venv/lib/python3.11/site-packages/fastapi/encoders.py", line 322, in jsonable_encoder
    data = dict(obj)
           ^^^^^^^^^
TypeError: cannot convert dictionary update sequence element #0 to a sequence

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/eminent/Documents/My codes/FastAPI/Tutorials/SocialAPI/venv/lib/python3.11/site-packages/fastapi/encoders.py", line 327, in jsonable_encoder
    data = vars(obj)
           ^^^^^^^^^
TypeError: vars() argument must have __dict__ attribute

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/home/eminent/Documents/My codes/FastAPI/Tutorials/SocialAPI/venv/lib/python3.11/site-packages/uvicorn/protocols/http/httptools_impl.py", line 426, in run_asgi
    result = await app(  # type: ignore[func-returns-value]
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eminent/Documents/My codes/FastAPI/Tutorials/SocialAPI/venv/lib/python3.11/site-packages/uvicorn/middleware/proxy_headers.py", line 84, in __call__
    return await self.app(scope, receive, send)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eminent/Documents/My codes/FastAPI/Tutorials/SocialAPI/venv/lib/python3.11/site-packages/fastapi/applications.py", line 1106, in __call__
    await super().__call__(scope, receive, send)
  File "/home/eminent/Documents/My codes/FastAPI/Tutorials/SocialAPI/venv/lib/python3.11/site-packages/starlette/applications.py", line 122, in __call__
    await self.middleware_stack(scope, receive, send)
  File "/home/eminent/Documents/My codes/FastAPI/Tutorials/SocialAPI/venv/lib/python3.11/site-packages/starlette/middleware/errors.py", line 184, in __call__
    raise exc
  File "/home/eminent/Documents/My codes/FastAPI/Tutorials/SocialAPI/venv/lib/python3.11/site-packages/starlette/middleware/errors.py", line 162, in __call__
    await self.app(scope, receive, _send)
  File "/home/eminent/Documents/My codes/FastAPI/Tutorials/SocialAPI/venv/lib/python3.11/site-packages/starlette/middleware/exceptions.py", line 79, in __call__
    raise exc
  File "/home/eminent/Documents/My codes/FastAPI/Tutorials/SocialAPI/venv/lib/python3.11/site-packages/starlette/middleware/exceptions.py", line 68, in __call__
    await self.app(scope, receive, sender)
  File "/home/eminent/Documents/My codes/FastAPI/Tutorials/SocialAPI/venv/lib/python3.11/site-packages/fastapi/middleware/asyncexitstack.py", line 20, in __call__
    raise e
  File "/home/eminent/Documents/My codes/FastAPI/Tutorials/SocialAPI/venv/lib/python3.11/site-packages/fastapi/middleware/asyncexitstack.py", line 17, in __call__
    await self.app(scope, receive, send)
  File "/home/eminent/Documents/My codes/FastAPI/Tutorials/SocialAPI/venv/lib/python3.11/site-packages/starlette/routing.py", line 718, in __call__
    await route.handle(scope, receive, send)
  File "/home/eminent/Documents/My codes/FastAPI/Tutorials/SocialAPI/venv/lib/python3.11/site-packages/starlette/routing.py", line 276, in handle
    await self.app(scope, receive, send)
  File "/home/eminent/Documents/My codes/FastAPI/Tutorials/SocialAPI/venv/lib/python3.11/site-packages/starlette/routing.py", line 66, in app
    response = await func(request)
               ^^^^^^^^^^^^^^^^^^^
  File "/home/eminent/Documents/My codes/FastAPI/Tutorials/SocialAPI/venv/lib/python3.11/site-packages/fastapi/routing.py", line 292, in app
    content = await serialize_response(
              ^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eminent/Documents/My codes/FastAPI/Tutorials/SocialAPI/venv/lib/python3.11/site-packages/fastapi/routing.py", line 180, in serialize_response
    return jsonable_encoder(response_content)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/eminent/Documents/My codes/FastAPI/Tutorials/SocialAPI/venv/lib/python3.11/site-packages/fastapi/encoders.py", line 301, in jsonable_encoder
    jsonable_encoder(
  File "/home/eminent/Documents/My codes/FastAPI/Tutorials/SocialAPI/venv/lib/python3.11/site-packages/fastapi/encoders.py", line 330, in jsonable_encoder
    raise ValueError(errors) from e
ValueError: [TypeError('cannot convert dictionary update sequence element #0 to a sequence'), TypeError('vars() argument must have __dict__ attribute')]      
              

python sqlalchemy fastapi
1个回答
0
投票

这应该可以修复您的代码:

@router.get("/posts")
def get_post(db: Session = Depends(get_db), current_user: int = Depends(oauth2.get_current_user), limit: int=10, skip: int= 0, search: Optional[str]=''):

     posts = db.query(models.Post).filter(models.Post.title.contains(search)).all()


    results = db.query(models.Post, func.count(models.Vote.post_id).label("votes")).join(
        models.Vote, models.Vote.post_id == models.Post.id, isouter=True).group_by(models.Post.id)

    new_results = db.execute(results).mappings().all()
    

    return new_results
© www.soinside.com 2019 - 2024. All rights reserved.