I am trying to update a single record in the database by using the PUT operation in FastAPI. But for some reason, I keep getting this error. All other operations work fine except this one. The error is only raised for the update query.
AttributeError: 'Blog' object has no attribute 'items'
Here is the relevant code.
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()
This is the 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'
This worked for me... the update function wanted to update each part of the object, and so each part must be mentioned. I'm not certain how Bitfumes managed by calling the request object alone.
blog.update({'title': request.title, 'body': request.body})
EDITED: Referring the to the request dictionary works too:
blog.update(request.dict())