I have db table model with foreign key to another table:
class Vehicle(Base):
"""
Vehicles db table.
"""
__tablename__ = "vehicle"
id: Mapped[int] = mapped_column(primary_key=True)
license_plate: Mapped[str] = mapped_column(String(20))
garage_number: Mapped[Optional[str]] = mapped_column(String(20))
brand: Mapped[str] = mapped_column(String(255))
base_location: Mapped[Optional[WKBElement]] = mapped_column(
Geometry(geometry_type="POINT", srid=4326, spatial_index=True)
)
vehicle_type = relationship("VehicleType", back_populates="vehicles")
vehicle_type_id: Mapped[int] = mapped_column(
ForeignKey("vehicle_type.id", ondelete="RESTRICT")
)
Pydantic model:
class VehicleCreate(BaseModel):
"""
Base vehicle schema.
"""
license_plate: str = Field(max_length=20)
garage_number: str = Field(max_length=20)
brand: str = Field(max_length=255)
vehicle_type_id: int
Post method:
@router.post("/", response_model=VehicleRead, status_code=status.HTTP_201_CREATED)
def create_vehicle(vehicle_in: VehicleCreate, db_session: Session = Depends(get_db)):
"""
Create a new vehicle.
"""
return service.create_vehicle(db_session=db_session, vehicle_in=vehicle_in)
Service:
def create_vehicle(db_session: Session, vehicle_in: VehicleCreate) -> Vehicle:
"""
Creates a vehicle.
"""
vehicle = Vehicle(**vehicle_in.model_dump())
db_session.add(vehicle)
db_session.commit()
db_session.refresh(vehicle)
return vehicle
So the main problem is that i have to validate if vehicle_type_id field value exists db. If i don’t validate that, i’ll get IntegrityError.
sqlalchemy.exc.IntegrityError: (psycopg2.errors.ForeignKeyViolation) insert or update on table "vehicle" violates foreign key constraint "vehicle_vehicle_type_id_fkey"
DETAIL: Key (vehicle_type_id)=(0) is not present in table "vehicle_type".
But in which layer?
I can’t do it in pydantic model because i don’t have access to session in it.
I can do it in view and return JSONResponse with corresponding error and 422 status. But i think it’s not the place.
I think the best place in service module inside create function, but i don’t know how to raise pydantic ValidationError outside the model.
Django rest framework has similar functionality in serializers, namely PrimaryKeyRelatedField.