Лучший способ указать вложенный dict с pydanti c? - PullRequest
0 голосов
/ 05 августа 2020

Контекст

Я пытаюсь проверить / проанализировать некоторые данные с помощью pydantic.

Я хочу указать, может ли dict иметь ключ daytime или нет. Если это так, я хочу, чтобы значение daytime включало как sunrise, так и sunset.

, например, они должны быть разрешены:

{
   'type': 'solar',
   'daytime': {
      'sunrise': 4, # 4am
      'sunset': 18 # 6pm
   }
}

и

{
   'type': 'wind'
   # daytime key is omitted
}

И

{
   'type': 'wind',
   'daytime': None
}

Но я хочу, чтобы проверка не прошла для

{
   'type': 'solar',
   'daytime': {
      'sunrise': 4
   }
}

, потому что это имеет значение daytime, но не значение заката.

MWE

У меня есть код, который это делает. Если я запускаю этот скрипт, он выполняется успешно.

from pydantic import BaseModel, ValidationError
from typing import List, Optional, Dict

class DayTime(BaseModel):
    sunrise: int
    sunset: int
    
class Plant(BaseModel):
    daytime: Optional[DayTime] = None
    type: str

p = Plant.parse_obj({'type': 'wind'})
p = Plant.parse_obj({'type': 'wind', 'daytime': None})
p = Plant.parse_obj({
    'type': 'solar', 
    'daytime': {
        'sunrise': 5, 
        'sunset': 18
    }})
    
try:
    p = Plant.parse_obj({
        'type': 'solar', 
        'daytime': {
            'sunrise': 5
        }})
except ValidationError:
    pass
else:
    raise AssertionError("Should have failed")

Вопрос

Мне интересно, это то, как вы должны использовать pydanti c для вложенные данные?

У меня много уровней вложенности, и это кажется немного многословным.

Есть ли способ сделать что-то более краткое, например:

class Plant(BaseModel):
    daytime: Optional[Dict[('sunrise', 'sunset'), int]] = None
    type: str

1 Ответ

1 голос
/ 05 августа 2020

Pydanti c create_model функция - это именно то, что вам нужно:

from pydantic import BaseModel, create_model

class Plant(BaseModel):
    daytime: Optional[create_model('DayTime', sunrise=(int, ...), sunset=(int, ...))] = None
    type: str
...