Вводятся следующие данные
data = {
'campaigns': [
{
'title': 'GBP',
'geo_segment': 'WW',
'ac_type': 'Value',
'conversion': 'soft',
'asset_type': 'ALL',
'date': '22.04.21',
'name': 'GBP_WW_1_core_22.04.21',
'budget': '2000',
'cpa': '1,00'
}
],
'stages': [
'pre',
'post'
],
'language_mode': 'all_en'
}
Для разбора campaigns
я использую метод parse_obj()
campaigns = parse_obj_as(List[CampaignData], data['campaigns'])
class CampaignData(BaseModel):
title: NonEmptyString
geo_segment: NonEmptyString
......
Оно работает.
Как проверить остальные данные (stages
:List
, language_mode
:str
), которые не относятся к типу dict
?
class GoogleCheckCampaignStages(BaseModel):
stages: List[str]
class GoogleCheckLanguageMode(BaseModel):
language_mode: str
Если я побегу
stages = parse_obj_as(List[GoogleCheckCampaignStages], data['stages'])
возвращается
value is not a valid dict (type=type_error.dict)
Тот же результат с data['language_mode']
.
Если я попробую методом parse_raw_as()
parse_raw_as(GoogleCheckLanguageMode, data['language_mode'])
возвращается
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
Итак, как разобрать значения str
и list
?
Ошибка, с которой вы сталкиваетесь, связана с тем, что вы передаете data["stages"]
, который является просто списком/массивом. У него нет ключа с именем stages
, и поэтому Pydantic не знает, как его назначить.
Предполагая, что NonEmptyString
определено, как показано ниже, я бы предложил создать одну модель, которая обрабатывает весь объект data
, например, так:
from pydantic import BaseModel, parse_obj_as, constr
from typing import List
NonEmptyString = constr(min_length=1)
class CampaignData(BaseModel):
title: NonEmptyString
geo_segment: NonEmptyString
# and so on ...
class Data(BaseModel):
campaigns: List[CampaignData]
stages: List[str]
language_mode: str
parsed_data = parse_obj_as(Data, data)
print(parsed_data)
# campaigns=[CampaignData(title='GBP', geo_segment='WW', ...)] stages=['pre', 'post'] language_mode='all_en'
Если вы хотите получить доступ только к определенным элементам, вы можете легко сделать это следующим образом:
print(parsed_data.stages)
# ['pre', 'post']