Check out these Pydantic models, AuthorSchema
and BookSchema
from typing import List, Optional
from pydantic import BaseModel
class AuthorSchema(BaseModel):
id: int
name: str
blurb: Optional[str]
class Config:
orm_mode = True
class BookSchema(BaseModel):
id: int
title: str
authors: List[AuthorSchema]
class Config:
orm_mode = True
A Book can contain multiple Authors. Furthermore, an Author can have a blurb
. (A blurb is a note about an author, relative to his work on a specific book.)
I have three corresponding classes for Book
, Author
, and BookAuthor
.
class Author:
def __init__(self, id: int, name: str):
self.id = id
self.name = name
class Book:
def __init__(self, id: int, title: str):
self.id = id
self.title = title
class BookAuthor:
def __init__(self, book: Book, author: Author, blurb: str):
self.book = book
self.author = author
self.blurb = blurb
My goal is to populate a BookSchema instance with multiple related Authors. Here's a demo of my attempt
Demo (Attempt)
bob = Author(id=1, name='Bob')
sue = Author(id=2, name='Sue')
book1 = Book(id=1, title="Foo")
book1.authors = [
BookAuthor(book=book1, author=bob, blurb='Bob is a scientist who wrote chapters 1-3'),
BookAuthor(book=book1, author=sue, blurb='Sue is an economist who wrote chapter 4')
]
print(book1.title) # Foo
print(book1.authors[0].blurb) # Bob is a scientist who wrote chapters 1-3
print(book1.authors[0].author.name) # Bob
AuthorSchema.from_orm(bob) # works
BookSchema.from_orm(book1) # errors
BookSchema.from_orm(book1)
errors because it expects book1.authors[0]
to have a .id
attribute. Obviously, it doesn't. To access the id
attribute one must do book1.authors[0].author.id
.
Unfortunately I cannot alter the shape of my incoming data. I also don't want to change the structure of my Pydantic models. So, how can I populate my Pydantic model given my input data, considering they are misaligned in their structure?