[QUESTION] Getting Validation Error on Response, using Alchemysql + FastAPI
See original GitHub issueDescription
i’m getting a validation error on my API, not sure what’s wrong with it, i followed the example at SQL (Relational) Databases i think it’s a problem with the pydantic models, i’m still not sure if defining it correctly.
here’s the package version that i’m using
- fastapi 0.63.0
- pydantic 1.7.3
- SQLAlchemy 1.3.22
here’s the error Traceback
2021-01-12 20:38:26,463 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2021-01-12 20:38:26,464 INFO sqlalchemy.engine.base.Engine SELECT device.id AS device_id, device.macaddress AS device_macaddress, device.name AS device_name
FROM device
2021-01-12 20:38:26,465 INFO sqlalchemy.engine.base.Engine ()
2021-01-12 20:38:26,478 INFO sqlalchemy.engine.base.Engine SELECT record.id AS record_id, record.timestamp AS record_timestamp, record.image AS record_image, record.reading AS record_reading, record.device_id AS record_device_id
FROM record
WHERE ? = record.device_id
2021-01-12 20:38:26,479 INFO sqlalchemy.engine.base.Engine (1,)
2021-01-12 20:38:26,481 INFO sqlalchemy.engine.base.Engine SELECT record.id AS record_id, record.timestamp AS record_timestamp, record.image AS record_image, record.reading AS record_reading, record.device_id AS record_device_id
FROM record
WHERE ? = record.device_id
2021-01-12 20:38:26,482 INFO sqlalchemy.engine.base.Engine (2,)
INFO: 127.0.0.1:64156 - "GET /devices/ HTTP/1.1" 500 Internal Server Error
2021-01-12 20:38:26,484 INFO sqlalchemy.engine.base.Engine ROLLBACK
ERROR: Exception in ASGI application
Traceback (most recent call last):
File "e:\repo\tubes iot\env\lib\site-packages\uvicorn\protocols\http\h11_impl.py", line 394, in run_asgi
result = await app(self.scope, self.receive, self.send)
File "e:\repo\tubes iot\env\lib\site-packages\uvicorn\middleware\proxy_headers.py", line 45, in __call__
return await self.app(scope, receive, send)
File "e:\repo\tubes iot\env\lib\site-packages\fastapi\applications.py", line 199, in __call__
await super().__call__(scope, receive, send)
File "e:\repo\tubes iot\env\lib\site-packages\starlette\applications.py", line 111, in __call__
await self.middleware_stack(scope, receive, send)
File "e:\repo\tubes iot\env\lib\site-packages\starlette\middleware\errors.py", line 181, in __call__
raise exc from None
File "e:\repo\tubes iot\env\lib\site-packages\starlette\middleware\errors.py", line 159, in __call__
await self.app(scope, receive, _send)
File "e:\repo\tubes iot\env\lib\site-packages\starlette\exceptions.py", line 82, in __call__
raise exc from None
File "e:\repo\tubes iot\env\lib\site-packages\starlette\exceptions.py", line 71, in __call__
await self.app(scope, receive, sender)
File "e:\repo\tubes iot\env\lib\site-packages\starlette\routing.py", line 566, in __call__
await route.handle(scope, receive, send)
File "e:\repo\tubes iot\env\lib\site-packages\starlette\routing.py", line 227, in handle
await self.app(scope, receive, send)
File "e:\repo\tubes iot\env\lib\site-packages\starlette\routing.py", line 41, in app
response = await func(request)
File "e:\repo\tubes iot\env\lib\site-packages\fastapi\routing.py", line 209, in app
response_data = await serialize_response(
File "e:\repo\tubes iot\env\lib\site-packages\fastapi\routing.py", line 126, in serialize_response
raise ValidationError(errors, field.type_)
pydantic.error_wrappers.ValidationError: 4 validation errors for Device
response -> 0 -> maccaddress
field required (type=value_error.missing)
response -> 0 -> records -> 0 -> reading
none is not an allowed value (type=type_error.none.not_allowed)
response -> 0 -> records -> 1 -> reading
none is not an allowed value (type=type_error.none.not_allowed)
response -> 1 -> maccaddress
field required (type=value_error.missing)
schemas.py
from typing import List, Optional
from pydantic import BaseModel
import datetime
class Record(BaseModel):
id : int
timestamp : datetime.datetime
image : Optional[str]
device_id : int
reading : int
class Config :
orm_mode= True
class Device(BaseModel):
id : int
maccaddress : str
name : Optional[str] = None
records : List[Record] =[]
class Config :
orm_mode = True
class DeviceChange(Device):
name : str
models.py
class Device(Base):
__tablename__ = 'device'
id = Column(Integer, primary_key=True)
macaddress = Column(String, unique=True)
name = Column(String)
records = relationship("Record",back_populates='device')
class Record(Base):
__tablename__ = 'record'
id = Column(Integer, primary_key=True)
timestamp = Column(DateTime(timezone=False),default=func.now())
image = Column(String)
reading = Column(Integer)
device_id = Column(Integer, ForeignKey('device.id'))
device = relationship("Device",back_populates='records')
crud.py
from sqlalchemy.orm import Session
import models, schemas, datetime
def get_devices(db : Session) :
return db.query(models.Device).all()
def get_device(db : Session, dev_id : int) :
return db.query(models.Device).filter(models.Device.id == dev_id).first()
def get_records(db : Session, date: datetime, dev_id : int) :
return db.query(models.Record).filter(
(models.Record.timestamp.like('%'+date+'%')),
(models.Record.device_id == dev_id)
).all()
def set_name(db : Session, name : str, dev_id : int):
query = db.query(models.Device).filter(
models.Device.id == dev_id
).first()
query.name = name
db.commit()
return query
main.py
app = FastAPI()
# Dependency
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
# Return all Devices
@app.get("/devices/", response_model=List[schemas.Device])
def read_devices(db : Session = Depends(get_db)):
devices = crud.get_devices(db)
return devices
# Return Device
@app.get("/devices/{device_id}", response_model=schemas.Device)
def read_device(device_id : int,db : Session = Depends(get_db)):
device = crud.get_device(db,device_id)
return device
# Return device records list
@app.get("/devices/{device_id}/records/{date}", response_model=List[schemas.Record])
def read_records(date : datetime.datetime, device_id : int, db : Session = Depends(get_db)):
records = crud.get_records(db,date,device_id)
return records
# Return Device latest record
@app.get("/devices/{device_id}/records/latest", response_model=schemas.Record)
def read_latest(device_id : int, db : Session = Depends(get_db)):
record = crud.get_latest(db,device_id)
return record.reading
Issue Analytics
- State:
- Created 3 years ago
- Comments:5 (3 by maintainers)
Top Results From Across the Web
FastApi get request shows validation error - Stack Overflow
So with this schema i get the same error response -> name field required (type=value_error.missing) response -> value field required ...
Read more >Handling Errors - FastAPI
These handlers are in charge of returning the default JSON responses when you raise an HTTPException and when the request has invalid data....
Read more >Many-To-Many Relationships In FastAPI - GormAnalysis
In this tutorial, I cover multiple strategies for handling many-to-many relationships using FastAPI with SQLAlchemy and pydantic.
Read more >How to Implement Pagination Using FastAPI in Python
Use fastapi -pagination library to paginate API responses ... Note: If you get duplicate key errors, try inserting fewer rows at a time...
Read more >FastAPI with SQLAlchemy Tutorial - YouTube
In this video, Jose Haro Peralta explains how to use SQLAlchemy in a FAstAPI application.The code for this tutorial is available in GitHub: ......
Read more >
Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free
Top Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Update : i fixed the problem by changing the pydantic variable in
Record
Class to optionalthanks everyone i’m really sorry for creating stupid issues like this
Thanks for the help here everyone! 👏 🙇
Thanks for reporting back and closing the issue 👍