验证器和额外列在 pydantic 2.* 中都有不同的配置方式,我想知道我是否仍然可以进行验证以获取所有额外字段并将它们放入单个字典字段中
预期的行为是:
class A(BaseModel):
name: str
extra_columns: Optional[Dict]
a = A(name="john", age=24, address="Brazil")
print(a)
>>> A(name="john", extra_columns={"age": 24, "address": "Brazil"})
我之前的代码:
@root_validator(pre=True)
def build_extra(cls, values: Dict[str, Any]) -> Dict[str, Any]:
all_required_field_names = {
field.alias for field in cls.__fields__.values() if field.alias != "extra_columns"
}
extra: Dict[str, Any] = {}
for field_name in list(values):
if field_name not in all_required_field_names:
extra[field_name] = values.pop(field_name)
values["extra_columns"] = extra
return values
是否可以在 pydantic 2.* 中采取相同的行为?
这可以通过model_validator来解决:
from typing import Any
from pydantic import BaseModel, model_validator
class A(BaseModel):
name: str
extra_columns: dict | None = None
@model_validator(mode="before")
@classmethod
def set_extra_columns(cls, data: Any):
if isinstance(data, dict):
extra_fields = data.keys() - cls.model_fields.keys()
if extra_fields:
if "extra_columns" not in data:
data["extra_columns"] = {}
data["extra_columns"].update(
{field_name: data[field_name] for field_name in extra_fields}
)
return data
a = A(name="john", age=24, address="Brazil")
print(a)
# >>> name='john' extra_columns={'age': 24, 'address': 'Brazil'}