AttributeError: 'Blog' object has no attribute 'items' - FastAPI

AttributeError: 'Blog' object has no attribute 'items' - FastAPI

我正在尝试使用 FastAPI 中的 PUT 操作更新数据库中的单个记录。但出于某种原因,我不断收到此错误。除此操作外,所有其他操作均正常。仅针对更新查询引发错误。

AttributeError: 'Blog' object has no attribute 'items'

这里是相关代码。

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

class Blog(BaseModel):
    title: str
    body: str

@app.put('/blog/{id}', status_code=status.HTTP_204_NO_CONTENT, response_class=Response)
def update(id: int, request: schemas.Blog, db: Session = Depends(get_db)):
    blog = db.query(models.Blog).filter(models.Blog.id == id)
    if not blog.first():
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,
                            detail=f'Blog with id {id} not found')
    blog.update(request)
    db.commit()

这是 StackTrace:

Traceback (most recent call last):
  File "c:\dev\fast-tuts\env\lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 396, in run_asgi        
    result = await app(self.scope, self.receive, self.send)
  File "c:\dev\fast-tuts\env\lib\site-packages\uvicorn\middleware\proxy_headers.py", line 45, in __call__        
    return await self.app(scope, receive, send)
  File "c:\dev\fast-tuts\env\lib\site-packages\fastapi\applications.py", line 199, in __call__
    await super().__call__(scope, receive, send)
  File "c:\dev\fast-tuts\env\lib\site-packages\starlette\applications.py", line 111, in __call__
    await self.middleware_stack(scope, receive, send)
  File "c:\dev\fast-tuts\env\lib\site-packages\starlette\middleware\errors.py", line 181, in __call__
    raise exc from None
  File "c:\dev\fast-tuts\env\lib\site-packages\starlette\middleware\errors.py", line 159, in __call__
    await self.app(scope, receive, _send)
  File "c:\dev\fast-tuts\env\lib\site-packages\starlette\exceptions.py", line 82, in __call__
    raise exc from None
  File "c:\dev\fast-tuts\env\lib\site-packages\starlette\exceptions.py", line 71, in __call__
    await self.app(scope, receive, sender)
  File "c:\dev\fast-tuts\env\lib\site-packages\starlette\routing.py", line 566, in __call__
    await route.handle(scope, receive, send)
  File "c:\dev\fast-tuts\env\lib\site-packages\starlette\routing.py", line 227, in handle
    await self.app(scope, receive, send)
  File "c:\dev\fast-tuts\env\lib\site-packages\starlette\routing.py", line 41, in app
    response = await func(request)
  File "c:\dev\fast-tuts\env\lib\site-packages\fastapi\routing.py", line 201, in app
    raw_response = await run_endpoint_function(
  File "c:\dev\fast-tuts\env\lib\site-packages\fastapi\routing.py", line 150, in run_endpoint_function
    return await run_in_threadpool(dependant.call, **values)
  File "c:\dev\fast-tuts\env\lib\site-packages\starlette\concurrency.py", line 34, in run_in_threadpool
    return await loop.run_in_executor(None, func, *args)
  File "C:\Python39\lib\concurrent\futures\thread.py", line 52, in run
    result = self.fn(*self.args, **self.kwargs)
  File ".\blog\main.py", line 66, in update
    blog.update(request)
  File "c:\dev\fast-tuts\env\lib\site-packages\sqlalchemy\orm\query.py", line 3190, in update
    upd = upd.values(values)
  File "<string>", line 2, in values
  File "c:\dev\fast-tuts\env\lib\site-packages\sqlalchemy\sql\base.py", line 96, in _generative
    x = fn(self, *args, **kw)
  File "<string>", line 2, in values
  File "c:\dev\fast-tuts\env\lib\site-packages\sqlalchemy\sql\base.py", line 125, in check
    return fn(self, *args, **kw)
  File "c:\dev\fast-tuts\env\lib\site-packages\sqlalchemy\sql\dml.py", line 701, in values
    for k, v in arg.items()
AttributeError: 'Blog' object has no attribute 'items'

您必须遍历博客对象的属性并逐一更新它们。你可以按照这个例子:https://github.com/tiangolo/full-stack-fastapi-postgresql/blob/master/%7B%7Bcookiecutter.project_slug%7D%7D/backend/app/app/crud/base.py#L49

这对我有用...更新函数想要更新对象的每个部分,因此必须提及每个部分。我不确定 Bitfumes 如何通过单独调用请求对象来管理。

blog.update({'title': request.title, 'body': request.body})

已编辑: 引用请求字典也有效:

blog.update(request.dict())

试试这个:

@app.put("/blog/update/{id}")
def updateBlog(id, request:schemas.Blog, db:Session=Depends(get_db)):
   blog= db.query(model.Blog).filter(model.Blog.id == id).first()
   
   if not blog:
             raise HTTPException(status_code=status.HTTP_404_NOT_FOUND,detail=f'blog with id {id} not found')
   else:
  db.query(model.Blog).filter(model.Blog.id == id).update(request.dict())

db.commit()
db.refresh(blog)
return blog

我也遇到了这个问题。 Blog 不是字典,这是一个 Pydentic Base 模型。 如果我们检查博客类型,我们会到达这里

<class 'blog.schemas.Blog'>

这不是密钥对字典,这就是为什么它显示我们没有属性“项目”。 只有 dict 可以保存项目和值,所以我们需要将 Blog schema 转换为 字典.

我也遇到了同样的问题。但是,我在打印请求后意识到,显示:

"title='strinaaaaaag' body='asasa'"

因此要解决此问题,只需将您的 'request' 转换为字典类型:

dict(request)