簡體   English   中英

Pydantic - 在 ValidationError 上打印 object 並從列表中刪除

[英]Pydantic - Print object on ValidationError and remove from list

背景

我正在開發一個應用程序,它需要一個模塊來驗證 JSON 數據。 提供的 JSON 數據可能有500 - 2000個條目。 我不確定選擇 Pydantic 是否是實現預期結果的正確方法(問題部分)。 由於應用程序非常復雜,我提供了一個最小的示例。

問題

  1. 當 Pydantic 引發ValidationError時,如何獲取 object 及其值? 在給定的示例中{'name': 'FISH', 'is_dry': False, 'price': 3.30}是無效項目,但 output 僅指示錯誤而不是 object name \n Item is not part of inventory and is skipped. (type=value_error) name \n Item is not part of inventory and is skipped. (type=value_error) 這在嘗試確定哪些項目未通過驗證時沒有幫助。 此外,我的目標是記錄 object 信息以供將來參考。

  2. Pydantic 是否提供獲取有效和無效項目的功能? 根據我的示例,我必須手動將 append 有效項目添加到單獨的列表中。

    有效項目

    [ Food(name='XA_APPLE', is_dry=True, price=0.3), Food(name='XA_RICE', is_dry=True, price=0.5) ]

    無效項目

    [ Food(name='FISH', is_dry=False, price=3.30), Food(name='FISH', is_dry=False, price=3.30) ]
  3. 是否有一種更 Pythonic 的方式來使用帶有 try 塊的列表理解重寫此代碼?

     # The following statement uses list comprehension but # stops executing when an exception is raise as there # is no try block to catch the exception. # foods = [Food(**food) for food in foods] # Hence, I resulted in using the following piece of code. for food in foods: try: valid_foods.append(Food(**food)) except pydantic.ValidationError as err: print(err, '-'* 30, sep='\n', end='\n')

代碼

進口

import pydantic

Pydantic model 帶驗證器

class Food(pydantic.BaseModel):

    name: str
    is_dry: bool
    price: float

    @pydantic.validator('name')
    def validate_name(cls, value: str) -> str:

        if not value.startswith('XA_'):
            raise ValueError('Item is not part of inventory and is skipped.')

        return value

加載值並驗證

# List is to simulate a loaded JSON structure.
foods = [
    {'name': 'XA_APPLE', 'is_dry': True, 'price': 0.30},
    {'name': 'FISH', 'is_dry': False, 'price': 3.30},
    {'name': 'XA_RICE', 'is_dry': True, 'price': 0.50},
    {'name': 'FISH', 'is_dry': False, 'price': 3.30},
]

valid_foods = []

for food in foods:

    try:
        valid_foods.append(Food(**food))

    except pydantic.ValidationError as err:
        print(err, '-'* 30, sep='\n')

print(valid_foods, '-'* 30, sep='\n')

Output

1 validation error for Food
name
  Item is not part of inventory and is skipped. (type=value_error)
------------------------------
1 validation error for Food
name
  Item is not part of inventory and is skipped. (type=value_error)
------------------------------
[Food(name='XA_APPLE', is_dry=True, price=0.3), Food(name='XA_RICE', is_dry=True, price=0.5)]
------------------------------

您將需要一個額外的 model:

class Foods(BaseModel):

    foods: list[Food]

    @validator('foods', each_item=True)
    def validator_logic(cls, v):
        if value.startswith('XA_'):
            return v
        else:
            log.error({'invalid': v})

Pydantic 允許遞歸模型和驗證器允許通過參數each_item對每個項目進行驗證,因此:

  1. 您可以在記錄無效項目的地方使用上述驗證器塊代碼。
  2. 我不知道一些設置有效/無效的方法,我相信你必須自己實現
  3. 不需要使用上面的 model。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM