[英]Error Value not declarable with JSON Schema for PurePath with Pydantic and FastAPI
我正在嘗試將PureWindowsPath
類型的字段path
添加到我的模型中。 在按照此處建議的https://github.com/samuelcolvin/pydantic/issues/2089#issuecomment-890018075實施自定義驗證器后,嘗試訪問 SwaggerUI 時出現以下錯誤:
INFO: 127.0.0.1:7696 - "GET /api/openapi.json HTTP/1.1" 500 Internal Server Error
ERROR: Exception in ASGI application
Traceback (most recent call last):
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\uvicorn\protocols\http\httptools_impl.py", line 371, in run_asgi
result = await app(self.scope, self.receive, self.send)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\uvicorn\middleware\proxy_headers.py", line 59, in __call__
return await self.app(scope, receive, send)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\fastapi\applications.py", line 208, in __call__
await super().__call__(scope, receive, send)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\applications.py", line 112, in __call__
await self.middleware_stack(scope, receive, send)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\middleware\errors.py", line 181, in __call__
raise exc from None
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\middleware\errors.py", line 159, in __call__
await self.app(scope, receive, _send)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\exceptions.py", line 82, in __call__
raise exc from None
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\exceptions.py", line 71, in __call__
await self.app(scope, receive, sender)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\routing.py", line 580, in __call__
await route.handle(scope, receive, send)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\routing.py", line 390, in handle
await self.app(scope, receive, send)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\fastapi\applications.py", line 208, in __call__
await super().__call__(scope, receive, send)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\applications.py", line 112, in __call__
await self.middleware_stack(scope, receive, send)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\middleware\errors.py", line 181, in __call__
raise exc from None
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\middleware\errors.py", line 159, in __call__
await self.app(scope, receive, _send)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\exceptions.py", line 82, in __call__
raise exc from None
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\exceptions.py", line 71, in __call__
await self.app(scope, receive, sender)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\routing.py", line 580, in __call__
await route.handle(scope, receive, send)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\routing.py", line 241, in handle
await self.app(scope, receive, send)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\starlette\routing.py", line 52, in app
response = await func(request)
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\fastapi\applications.py", line 161, in openapi
return JSONResponse(self.openapi())
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\fastapi\applications.py", line 136, in openapi
self.openapi_schema = get_openapi(
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\fastapi\openapi\utils.py", line 387, in get_openapi
definitions = get_model_definitions(
File "C:\Users\xxx\.virtualenvs\server-J9mXI7Iu\lib\site-packages\fastapi\utils.py", line 24, in get_model_definitions
m_schema, m_definitions, m_nested_models = model_process_schema(
File "pydantic\schema.py", line 548, in pydantic.schema.model_process_schema
File "pydantic\schema.py", line 589, in pydantic.schema.model_type_schema
File "pydantic\schema.py", line 241, in pydantic.schema.field_schema
File "pydantic\schema.py", line 495, in pydantic.schema.field_type_schema
File "pydantic\schema.py", line 863, in pydantic.schema.field_singleton_schema
ValueError: Value not declarable with JSON Schema, field: name='path' type=PureWindowsPath required=True
我的 Pydantic 配置如下所示:
class CamelModel(BaseModel, ABC):
class Config:
alias_generator = camelize
allow_population_by_field_name = True
frozen = True
json_encoders = {
datetime: lambda dt: dt.isoformat(),
PureWindowsPath: str,
PurePath: str
}
use_enum_values = True
class Foo(CamelModel, ABC):
path: PureWindowsPath
extraction_version: str
class Foo2(Foo):
pass
您可以使用以下代碼來完成這項工作。 它創建了一個帶有驗證器的子類,因此您可以自定義架構和驗證方式:
這是相關 Github 問題的鏈接: https ://github.com/tiangolo/sqlmodel/issues/235#issuecomment-1162063590
from psycopg2.extras import DateTimeTZRange as DateTimeTZRangeBase
from sqlalchemy.dialects.postgresql import TSTZRANGE
from sqlmodel import (
Column,
Field,
Identity,
SQLModel,
)
from pydantic.json import ENCODERS_BY_TYPE
ENCODERS_BY_TYPE |= {DateTimeTZRangeBase: str}
class DateTimeTZRange(DateTimeTZRangeBase):
@classmethod
def __get_validators__(cls):
yield cls.validate
@classmethod
def validate(cls, v):
if isinstance(v, str):
lower = v.split(", ")[0][1:].strip().strip()
upper = v.split(", ")[1][:-1].strip().strip()
bounds = v[:1] + v[-1:]
return DateTimeTZRange(lower, upper, bounds)
elif isinstance(v, DateTimeTZRangeBase):
return v
raise TypeError("Type must be string or DateTimeTZRange")
@classmethod
def __modify_schema__(cls, field_schema):
field_schema.update(type="string", example="[2022,01,01, 2022,02,02)")
class EventBase(SQLModel):
__tablename__ = "event"
timestamp_range: DateTimeTZRange = Field(
sa_column=Column(
TSTZRANGE(),
nullable=False,
),
)
class Event(EventBase, table=True):
id: int | None = Field(
default=None,
sa_column_args=(Identity(always=True),),
primary_key=True,
nullable=False,
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.