Let's say that I have an pydantic (it could be any kind of) model that shold know how to convert itself to orm (it could be any kind of) model. To do so I have constructed mod_a.py:
from pydantic import BaseModel
from mod2mod.mod_b import DBUser
class User(BaseModel):
name: str
surname: str
def to_orm(self) -> DBUser:
return DBUser(
full_name = f"{self.surname},{self.name}"
)
I would also like my orm model to be able to convert itself to pydantic model, so my mod_b.py is:
from sqlalchemy.orm import declarative_base
from sqlalchemy import Column, Integer, String
from mod_a import User
Base = declarative_base()
class DBUser(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
full_name = Column(String)
def to_pydantic(self) -> User:
surname, name = self.full_name.split(',')
User(
name=name,
surname=surname
)
Idea is to be able to go from model to model at will like in mod2mod.py:
import pydantic
from mod_a import User
from mod_b import DBUser
user = User(name='John', surname='Doe')
orm_user = user.to_orm()
pydantic_user = orm_user.to_pydantic()
print(user)
print(pydantic_user)
Obviously this will not work because:
ImportError: cannot import name 'User' from partially initialized module 'mod_a' (most likely due to a circular import) (/mod2mod/mod_a.py)
How to solve this type of problem? Do I need another entity that will now how to do conversions between models and put current model methods there or there is some other design pattern?
You can use import ... style instead of from ... import .... And wrap return type hints in quotes (I did such below) or use postponed annotation evaluation PEP-563 (by the way, it is default for Python 3.10)
# mod_a.py
from pydantic import BaseModel
import mod_b
class User(BaseModel):
name: str
surname: str
def to_orm(self) -> 'mod_b.DBUser':
return mod_b.DBUser()
# mod_b.py
import mod_a
class DBUser:
def to_pydantic(self) -> 'mod_a.User':
return mod_a.User(
name="",
surname=""
)
You have to to do a local import and us TYPE_CHECKING to be able to do a type hint.
from typing import TYPE_CHECKING
from pydantic import BaseModel
if TYPE_CHECKING:
from mod2mod.mod_b import DBUser
class User(BaseModel):
name: str
surname: str
def to_orm(self) -> "DBUser":
from mod2mod.mod_b import DBUser
return DBUser(
full_name = f"{self.surname},{self.name}"
)
Do this for DBUser as well.
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