EDIT: add proper greetings 🙄
Hi guys,
Many thanks for this fantastic repo. It rocks. Not to mention https://dockerswarm.rocks/, I am now in the process to review all my projects from this base 🥇
Here is my question :
How can I declare a one-to-many relationship in the pydantic models?
Context
I have a first object 'Rule', that is attached to a second 'City'.
I have tried the following without success :
rules.py
from app.models.cities import City
class RuleBase(BaseModel):
mode: Optional[RuleMode] = None
value: Optional[float] = None
city: Optional[City] = None
cities.py
class City(BaseModel):
id: int
name: str
rules: Optional[List['Rule']]
Error in tests:
ImportError while loading conftest '/app/app/tests/conftest.py'.
app/app/tests/conftest.py:4: in <module>
from app.models.cities import City, Rectangle, Point
app/app/models/cities.py:50: in <module>
class City(BaseModel):
usr/local/lib/python3.6/site-packages/pydantic/main.py:179: in __new__
config=config,
usr/local/lib/python3.6/site-packages/pydantic/fields.py:118: in infer
schema=schema,
usr/local/lib/python3.6/site-packages/pydantic/fields.py:87: in __init__
self.prepare()
usr/local/lib/python3.6/site-packages/pydantic/fields.py:152: in prepare
self._populate_sub_fields()
usr/local/lib/python3.6/site-packages/pydantic/fields.py:177: in _populate_sub_fields
self.sub_fields = [self._create_sub_type(t, f'{self.name}_{display_as_type(t)}') for t in types_]
usr/local/lib/python3.6/site-packages/pydantic/fields.py:177: in <listcomp>
self.sub_fields = [self._create_sub_type(t, f'{self.name}_{display_as_type(t)}') for t in types_]
usr/local/lib/python3.6/site-packages/pydantic/fields.py:210: in _create_sub_type
model_config=self.model_config,
usr/local/lib/python3.6/site-packages/pydantic/fields.py:87: in __init__
self.prepare()
usr/local/lib/python3.6/site-packages/pydantic/fields.py:153: in prepare
self._populate_validators()
usr/local/lib/python3.6/site-packages/pydantic/fields.py:228: in _populate_validators
else find_validators(self.type_, self.model_config.arbitrary_types_allowed)
usr/local/lib/python3.6/site-packages/pydantic/validators.py:326: in find_validators
raise RuntimeError(f'error checking inheritance of {type_!r} (type: {display_as_type(type_)})') from e
E RuntimeError: error checking inheritance of _ForwardRef('Rule') (type: _ForwardRef('Rule'))
Cheers,
Emmanuel
It won't answer your question exactly but I feel it's the same pattern where you have recursivity and declare an attribute of a model while that depends on another not yet created
my model looks like this :
<LoggerModel name='root' level=20 children=[<LoggerModel name='__main__' level=10 children=[]>, <LoggerModel name='__mp_ma…>
from __future__ import annotations
from typing import ForwardRef, List, Optional
from pydantic import BaseModel
ListLoggerModel = ForwardRef("List[LoggerModel]")
class LoggerModel(BaseModel):
name: str
level: Optional[int]
children: ListLoggerModel = None
LoggerModel.update_forward_refs()
Thanks for the hint!
I got an ImportError with python 3.6.8
>>> from typing import ForwardRef
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: cannot import name 'ForwardRef'
Therefore I installed python 3.7.3 and that solved the issue.
Probably something to report to https://github.com/tiangolo/full-stack-fastapi-postgresql, from which I started from :)
Forwardref is a python 3 thing indeed, maybe there s a way to achieve the
same without, @tiangolo will know for sure !
Le ven. 12 avr. 2019 à 7:59 PM, Manu notifications@github.com a écrit :
Thanks for the hint!
I got an ImportError with python 3.6.8
from typing import ForwardRef
Traceback (most recent call last):
File "", line 1, in
ImportError: cannot import name 'ForwardRef'Therefore I installed python 3.7.3 and that solved the issue.
Probably something to report to
https://github.com/tiangolo/full-stack-fastapi-postgresql, from which I
started from :)—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/tiangolo/fastapi/issues/153#issuecomment-482667182,
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABDZPnowf6UmatNDVrS7YpgPPMgkXMCnks5vgMlkgaJpZM4csUX5
.
Many thanks for this fantastic repo. It rocks. Not to mention https://dockerswarm.rocks/, I am now in the process to review all my projects from this base 🥇
That's cool! Thanks!
As @euri10 says, for that case, ForwardRef is the way to go.
The caveat is that ForwardRef is Python 3.7 only. And Python 3.7 is not compatible yet with tools like Celery and TensorFlow :/
Hi @tiangolo ,
Thanks for the confirmation 👍
Fair enough for tensorflow. Celery seems to have catch up with python 3.7 and I have made a PR on the postgresql project Generator https://github.com/tiangolo/full-stack-fastapi-postgresql/pull/10 to test 3.7
Could you have a look at it ? Would it effectively allow the ForwardRef and ease the definition of relationships on a pydantic levels, that would be a great added value for a postgresql project 😇
Cheers,
Emmanuel
Awesome! I'll check it.
Just merged your PR. Now Celery and TensorFlow both support Python 3.7! :tada:
Hi, I'm sorry for resurrecting an old issue but I just ran into @ebreton's problem and I'd like to check if this is still the best practice. Considering an example similar to the docs:
item.py:
class Item(ItemBase):
id: int
owner: User # <------ Relationship with User
class Config:
orm_mode = True
user.py:
class User(UserBase):
id: int
is_active: bool
items: List[Item] = [] # <------ Relationship with Item
class Config:
orm_mode = True
I'd have to import both item from user.py and user from item.py, which would cause a circular import. So I should do something like
ListItem = ForwardRef("List[Item]")
class User(UserBase):
id: int
is_active: bool
items: ListItem = [] # <------ Relationship with Item
class Config:
orm_mode = True
User.update_forward_refs()
As my FastAPI application grows, I'd like to break the CRUD into a submodule and the schemas as well. Having back populated relationships like those make things difficult
Update: actually, I couldn't make it work...
Update 2: I think my problem is actually this one samuelcolvin/pydantic#659
My problem is the same as @fbidu .
Or @tiangolo are you against splitting schema into multiple files?
Same issue here. Can't manage to have 2 schemas referencing each others. What is the correct way to achieve this?
I have the same problem. Has anyone found a solution? @tiangolo
There is no correct way - two schemas referencing each other will cause an infinite loop, which you must break
What would be the best practice in this situation?
Most helpful comment
Hi, I'm sorry for resurrecting an old issue but I just ran into @ebreton's problem and I'd like to check if this is still the best practice. Considering an example similar to the docs:
item.py:user.py:I'd have to import both
itemfromuser.pyanduserfromitem.py, which would cause a circular import. So I should do something likeAs my FastAPI application grows, I'd like to break the CRUD into a submodule and the schemas as well. Having back populated relationships like those make things difficult
Update: actually, I couldn't make it work...
Update 2: I think my problem is actually this one samuelcolvin/pydantic#659