Fastapi Sqlalchemy 从从两个表中选择列的查询返回结果时出现类型错误

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

我从视频教程中复制了以下代码,它应该返回以下输出。

代码

@router.get('/', status_code= status.HTTP_200_OK)
def get_notes(db: Session = Depends(get_db)):
    
    posts = db.query(models.Post, func.count(models.Likes.post_id).label("likes")) \
.join(models.Likes, models.Likes.post_id == models.Post.post_id, isouter=True) \
.group_by(models.Post.post_id).all()

    return posts

根据视频教程的预期输出

[
    {
        "Post": {
            "user_id": 1,
            "title": "title1",
            "created_datetime": "2023-02-19T16:39:07.552186+00:00",
            "post_id": 1,
            "content": "content for post 1"
        },
        "likes": 0
    },
    {
        "Post": {
            "user_id": 1,
            "title": "title2",
            "created_datetime": "2023-02-19T16:39:04.426658+00:00",
            "post_id": 2,
            "content": "content for post 2"
        },
        "likes": 0
    },
    ....
]

但是发送此请求会导致 500 内部服务器错误。

File "C:\Users\apapa\AppData\Local\pypoetry\Cache\virtualenvs\fastapi-backend-curI0rdX-py3.10\lib\site-packages\fastapi\encoders.py", line 160, 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')]

打印

posts
变量显示其值是元组列表而不是字典列表。

[(<app.db.models.Post object at 0x00000246A03003A0>, 0), (<app.db.models.Post object at 0x00000246A0300400>, 0), (<app.db.models.Post object at 0x00000246A0300430>, 0), (<app.db.models.Post object at 0x00000246A0300460>, 0), (<app.db.models.Post object at 0x00000246A0300490>, 2)]

因此我已经规避了这个问题,我认为这并不理想,而且一开始就没有必要:

posts = [{"Post": {**post.__dict__}, "likes": likes} for post, likes in posts]
return posts

我很好奇视频教程最初是如何让它发挥作用的?或者如果我错过了任何可以避免这个奇怪问题的步骤?还是只有我有这个问题?

database sqlalchemy fastapi psycopg2 fastapi-crudrouter
1个回答
0
投票

我也在遵循相同的教程并面临同样的问题

问题出在教程使用的 SQLAlchemy==1.4.23 版本上。

我使用的是最新版本的 SQLAlchemy==2.0.19。

令人惊讶的是,查询返回两个 SQLAlchemy 版本的数据格式相同

降级到 SQLAlchemy==1.4.23 修复了问题

[(, 0), (, 0), (, 0), (, 0), (, 2)]

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