I'm new to Pydantic and trying to understand how/if I can create a new class instance. I've read through the Pydantic documentation and can't find an example doing anything similar.
My python code (prior to Pydantic) looks like:
class Person:
def __init__(self, id):
db_result = get_db_content(id) #lookup id in a database and return a result
self.name = db_result['name']
self.birth_year = db_result['birth_year']
p1 = Person(1234)
print(p1.name)
What would the corresponding code in Pydantic look like if I want to create a Person instance
based on an id? Also, is it possible with Pydantic to have multiple constructors for the same
class. For example:
p1 = Person(1234)
p2 = Person("Jane Doe")
I'm not sure if this is the most "pydantic" way to do things, but one approach to solving this problem is to use classmethods.
class Person(BaseModel):
id: int
name: str
birth_year: int
@classmethod
def from_id(cls, id: int) -> "Person":
db_result = get_db_content(id) #lookup id in a database and return a result
return cls(**db_result)
p1 = Person.from_id(1234)
print(p1.name)
You could use a standard __init__ for this:
from typing import Optional
from pydantic import BaseModel
def get_db_content(id):
return {
'name': f'hello {id}',
'birth_year': 2010,
}
class Person(BaseModel):
id: str
name: Optional[str]
birth_year: Optional[int]
def __init__(self, *a, **kw):
super().__init__(*a, **kw)
db_result = get_db_content(self.id)
self.name = db_result['name']
self.birth_year = db_result['birth_year']
person = Person(id='15')
print(person.dict())
# {'id': '15', 'name': 'hello 15', 'birth_year': 2010}
Although, personally I wouldn't do that. Pydantic classes are meant to be used as parsers/validators, not as fully functional object entities. Calling DB methods from a class like this directly couples your class to the db code and makes testing more difficult.
I would do this instead:
from pydantic import BaseModel
def get_db_content(id):
return {
'name': f'hello {id}',
'birth_year': 2010,
}
class Person(BaseModel):
id: str
name: str
birth_year: int
person = Person(id='15', **get_db_content('15'))
print(person.dict())
# {'id': '15', 'name': 'hello 15', 'birth_year': 2010}
NB: the code examples should be self-contained and work as-is.
edit: using standard dunder constructor instead of @root_validator
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With