@f1_rock

Как открыть json файл в pydantic?

Пытаюсь получить любое значение из фала json, к примеру тот же title

Пробовал прочитать json таким способом, выдает ошибку...

from pydantic import BaseModel

with open('data.json') as f:
  input_json = json.loads(f.read())

class Book(BaseModel):
  isbn_13: int

test = Book.parse_raw(input_json)
print(test)

TypeError                                 Traceback (most recent call last)
/usr/local/lib/python3.7/dist-packages/pydantic/main.cpython-37m-x86_64-linux-gnu.so in pydantic.main.BaseModel.parse_raw()

3 frames
TypeError: the JSON object must be str, bytes or bytearray, not list

During handling of the above exception, another exception occurred:

ValidationError                           Traceback (most recent call last)
/usr/local/lib/python3.7/dist-packages/pydantic/main.cpython-37m-x86_64-linux-gnu.so in pydantic.main.BaseModel.parse_raw()

ValidationError: 1 validation error for Book
__root__
  the JSON object must be str, bytes or bytearray, not list (type=type_error)


Пробовал так, тоже ошибка....

import json
from pydantic import BaseModel

with open('data.json') as f:
  input_json = json.loads(f.read())

class Book(BaseModel):
  title: str

my_json_str = json.dumps(input_json)
test = Book.parse_raw(my_json_str)

print(test)


ValueError                                Traceback (most recent call last)
/usr/local/lib/python3.7/dist-packages/pydantic/main.cpython-37m-x86_64-linux-gnu.so in pydantic.main.BaseModel.parse_obj()

ValueError: dictionary update sequence element #0 has length 8; 2 is required

The above exception was the direct cause of the following exception:

ValidationError                           Traceback (most recent call last)
2 frames
/usr/local/lib/python3.7/dist-packages/pydantic/main.cpython-37m-x86_64-linux-gnu.so in pydantic.main.BaseModel.parse_obj()

ValidationError: 1 validation error for Book
__root__
  Book expected dict not list (type=type_error)


Вот сам файл json:
[
  {
    "title": "Zero to One",
    "subtitle": "Notes on Startups, or How to Build the Future",
    "author": "Peter Thiel",
    "publisher": "Ballantine Books",
    "isbn_10": "0753555190",
    "isbn_13": "978-0753555194",
    "price": 14.29,
    "author2": {
      "name": "Peter Thiel",
      "verified": true
    }
  },
  {
    "title": "The Lean Startup",
    "subtitle": "How Relentless Change Creates Radically Successful Businesses",
    "author": "Eric Ries",
    "publisher": "Penguin UK",
    "isbn_10": "0670921602",
    "isbn_13": "978-0670921607",
    "price": 12.96
  },
  {
    "title": "A Promised Land",
    "author": "Barack Obama",
    "publisher": "Viking UK",
    "isbn_10": "0241491517",
    "isbn_13": "978-0241491515",
    "price": 31.74
  },
  {
    "title": "The Hard Thing about Hard Things",
    "subtitle": "Building a Business When There Are No Easy Answers",
    "author": "Ben Horowitz",
    "publisher": "HarperBusiness",
    "isbn_10": "0062273205",
    "isbn_13": "978-0062273208",
    "price": 15.55
  },
  {
    "title": "Design patterns",
    "subtitle": "Elements of reusable object-oriented software",
    "author": "Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides",
    "publisher": "Addison Wesley",
    "isbn_10": "0201633612",
    "isbn_13": "978-0201633610",
    "price": 50
  },
  {
    "title": "Clean Code",
    "subtitle": "A Handbook of Agile Software Craftsmanship",
    "author": "Robert Martin",
    "publisher": "Financial Times Prentice Hall",
    "isbn_10": "0132350882",
    "isbn_13": "978-0132350884",
    "price": 33.43
  }
]


Подскажите, что не так делаю?
  • Вопрос задан
  • 1510 просмотров
Решения вопроса 1
@twistfire92
Python backend developer
Давайте лучше отдельно укажу что как, а все вместе вы уже попробуете сами собрать.
1. если у вас есть файл data.json, то чтобы перевести из него данные в python объекты, достаточно использовать json.load()

with open('data.json') as f:
    data = json.load(f)


В data у вас будет список словарей, а не словарь. Поэтому надо будет делать обход списка.
Если вы хотите вытащить только title и author2.name, то стоит учитывать, что поле author2 есть далеко не во всех записях, так что это поле стоит делать кастомным

class Author2(BaseModel):
  name: str

class Book(BaseModel):
  title: str
  author2: Author2 | None


а дальше уже обходим список с распаковкой словарей в конструктор класса Book
books = [Book(**book) for book in data]
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
AlexNest
@AlexNest Куратор тега Python
Работаю с Python/Django
Переводить ошибки пробовали?
the JSON object must be str, bytes or bytearray, not list (type=type_error)

Book expected dict not list (type=type_error)

Если да, то у меня только один вариант - вы абсолютно не знаете основ python (в частности структуры данных) и использовать pydantic вам еще рано.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы