How can I define a recursive Pydantic model?
Here's an example of what I mean:
from typing import List
from pydantic import BaseModel
class Task(BaseModel):
name: str
subtasks: List[Task] = []
but when I run that I get the following error:
NameError Traceback (most recent call last)
<ipython-input-1-c6dca1d390fe> in <module>
2 from pydantic import BaseModel
3
----> 4 class Task(BaseModel):
5 name: str
6 subtasks: List[Task] = []
<ipython-input-1-c6dca1d390fe> in Task()
4 class Task(BaseModel):
5 name: str
----> 6 subtasks: List[Task] = []
7
NameError: name 'Task' is not defined
I looked through the documentation but couldn't find anything. For example, at the page on "Recursive Models" , but it seems to be about nesting subtypes of BaseModel
not about a recursive type definition.
Thanks for your help!
Either put from __future__ import annotations
at the top of the file, or change your annotation to List['Task']
.
The relevant pydantic documentation is here: https://pydantic-docs.helpmanual.io/usage/postponed_annotations/
But the error in your question is not pydantic specific, that's just how type annotations work.
I found myself in a situation in which I want to run a root validator on the class. What happens is that, although the above solution seem to work find in some cases, the value of the recursive field subtasks
doesn't show up in the values
dictionary parameter of the @root_validator
.
I ended up with declaring
subtasks: List[Dict]
and recursively build the subtasks objects in the @root_validator
:
subtasks = values.get('subtasks')
if subtasks:
values['subtasks']=[Task(**subtask) for subtask in subtasks]
Expanding on the accepted answer from Alex Hall:
From the Pydantic docs, it appears the call to update_forward_refs()
is still required whether or not annotations
is imported.
from typing import List
from pydantic import BaseModel
class Task(BaseModel):
name: str
subtasks: List['Task'] = []
Task.update_forward_refs()
or
# python3.7+
from __future__ import annotations
from typing import List
from pydantic import BaseModel
class Task(BaseModel):
name: str
subtasks: List[Task] = []
Task.update_forward_refs()
https://pydantic-docs.helpmanual.io/usage/postponed_annotations/#self-referencing-models
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.