[英]How to validate 2 nested json using Pydantic model in python?
test1 = {
"abx": [
{
"name": "toyota",
"colors": "abc",
"demo": [
{
"name1": "pqr",
"surname": "abc",
"columns": [
{
"name2": "demo",
"nameid": "1"
}
]
}
]
},
{
"name": "suzuki",
"colors": "deq",
"demo": [
{
"name1": "abc",
"surname": "asd",
"columns": [
{
"name2": "demo1",
"nameid": "2"
}
]
}
]
}
]
}
我有 2 個嵌套的 JSON 並且兩個響應都有隨機播放值。 我想匹配使用 Pydantic 模型在 Python 中進行測試。
有什么方法可以比較、驗證兩個響應嗎?
嵌套的 JSON 可以簡單地用嵌套的 Pydantic 模型表示。 每個 object 都可以映射到 model,並且 model 可以具有其他 Pydantic 模型或 Pydantic 模型列表的屬性。
你從最里面的對象開始:
{
"name2": "demo1",
"nameid": "2",
}
可以表示為:
from pydantic import BaseModel, constr
class Column(BaseModel):
name2: str
nameid: constr(regex="[0-9]+") # See: https://pydantic-docs.helpmanual.io/usage/types/#arguments-to-constr
In [2]: raw = {"name2": "demo1", "nameid": "2"}
In [3]: col = Column(**raw)
In [4]: col.name2
Out[4]: 'demo1'
In [5]: col.nameid
Out[5]: '2'
如果其中一個值錯誤,Pydantic 將引發驗證錯誤:
In [6]: raw = {"name2": 1, "nameid": True}
In [7]: col = Column(**raw)
...
ValidationError: 1 validation error for Column
nameid
string does not match regex "[0-9]+" (type=value_error.str.regex; pattern=[0-9]+)
然后向上移動到每個Column
的父 object:
{
"name1": "abc",
"surname": "asd",
"columns": [
{"name2": "demo1", "nameid": "2"},
],
}
然后可以表示為:
from pydantic import BaseModel, conlist
class Demo(BaseModel):
name1: str
surname: str
columns: conlist(Column, min_items=1) # See: https://pydantic-docs.helpmanual.io/usage/types/#arguments-to-conlist
我們重用了前面的Column
class 定義,也就是說columns
屬性是Column
的列表。 Pydantic 可以在Demo
下實例化和驗證Column
的每個屬性:
In [8]: raw
Out[8]: {'name1': 'abc', 'surname': 'asd', 'columns': [{'name2': 'demo1', 'nameid': '2'}]}
In [9]: demo = Demo(**raw)
In [11]: demo.name1
Out[11]: 'abc'
In [13]: demo.surname
Out[13]: 'asd'
In [14]: demo.columns
Out[14]: [Column(name2='demo1', nameid='2')]
In [15]: demo.columns[0].name2
Out[15]: 'demo1'
In [16]: demo.columns[0].nameid
Out[16]: '2'
同樣,如果任何值是錯誤的(無論是來自外部屬性還是來自最內部的屬性),Pydantic 將引發驗證錯誤:
In [20]: raw
Out[20]: {'name1': 'abc', 'surname': None, 'columns': [{'name2': 'demo1', 'nameid': '2'}]}
In [21]: demo = Demo(**raw)
...
ValidationError: 1 validation error for Demo
surname
none is not an allowed value (type=type_error.none.not_allowed)
In [27]: raw
Out[27]: {'name1': 'abc', 'surname': 'asd', 'columns': [{'name2': None, 'nameid': '2'}]}
In [28]: demo = Demo(**raw)
...
ValidationError: 1 validation error for Demo
columns -> 0 -> name2
none is not an allowed value (type=type_error.none.not_allowed)
然后,您再次向上移動到每個Demo
的父 object
{
"name": "suzuki",
"colors": "deq",
"demo": [
{
"name1": "abc",
"surname": "asd",
"columns": [
{"name2": "demo1", "nameid": "2"},
],
}
],
}
可以表示為
from pydantic import BaseModel, conlist
class Car(BaseModel):
name: str
colors: str
demo: conlist(Demo, min_items=1)
其中,與我們為Column
所做的一樣,我們有一個demo
屬性,它被建模為Demo
對象列表。 Pydantic 可以處理demo
的嵌套初始化和驗證,其中包括其內部Column
class。
最后,您將到達最上面的 object:
test1 = {
"abx": [
{...},
{...},
]
}
它有一個abx
屬性,它是Car
對象的列表
from pydantic import BaseModel, conlist
class Test(BaseModel):
abx: conlist(Car, min_items=1)
In [3]: obj = Test(**test1)
In [4]: obj
Out[4]: Test(abx=[Car(name='toyota', colors='abc', demo=[Demo(name1='pqr', surname='abc', columns=[Column(name2='demo', nameid='1')])]), Car(name='suzuki', colors='deq', demo=[Demo(name1='abc', surname='asd', columns=[Column(name2='demo1', nameid='2')])])])
In [5]: obj.abx[1]
Out[5]: Car(name='suzuki', colors='deq', demo=[Demo(name1='abc', surname='asd', columns=[Column(name2='demo1', nameid='2')])])
In [6]: obj.abx[1].demo[0]
Out[6]: Demo(name1='abc', surname='asd', columns=[Column(name2='demo1', nameid='2')])
您還可以在任何地方停止建模,例如,停止建模Car
並從原始abx
object 進行驗證:
In [15]: car1 = Car(**test1['abx'][0])
In [16]: car1
Out[16]: Car(name='toyota', colors='abc', demo=[Demo(name1='pqr', surname='abc', columns=[Column(name2='demo', nameid='1')])])
In [17]: car2 = Car(**test1['abx'][1])
In [18]: car2
Out[18]: Car(name='suzuki', colors='deq', demo=[Demo(name1='abc', surname='asd', columns=[Column(name2='demo1', nameid='2')])])
同樣,如果您有錯誤,即使在內部Column
model 的某個地方,您也會收到驗證錯誤。
這樣做的好處是您可以從最里面到最外面依次測試和驗證每個 object。 有關conlist
constr
的更多詳細信息,請查看 Pydantic 文檔中的約束類型以及其他字段類型和驗證器以獲取更復雜的驗證。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.