Question about splitting the sqlmodel model and causing circular references #942
-
First Check
Commit to Help
Example Code############ apps/item/model.py file############
from apps.auth.model import User
class Item(BaseModel, table=True):
__tablename__ = "items"
__table_args__ = ({"comment": "Item Table"})
title: str = Field(sa_column_kwargs={"comment": "标题"}, max_length=50, nullable=False)
description: Optional[str] = Field(sa_column_kwargs={"comment": "描述"}, max_length=255, nullable=True)
owner_id: int = Field(default=None, foreign_key="auth_users.id", nullable=False)
owner: Optional["User"] = Relationship(back_populates="items")
############ apps/auth/model.py file############
from apps.item.model import Item
class User(BaseModel, table=True):
__tablename__ = "auth_users"
__table_args__ = ({"comment": "User Table"})
username: str = Field(sa_column_kwargs={"comment": "用户名"}, max_length=50, index=True, nullable=True, unique=True)
hashed_password: str = Field(sa_column_kwargs={"comment": "密码"}, max_length=200, nullable=False)
avatar: Optional[str] = Field(sa_column_kwargs={"comment": "头像"}, max_length=200, nullable=True)
nickname: Optional[str] = Field(sa_column_kwargs={"comment": "昵称"}, max_length=50, nullable=True)
phone: Optional[str] = Field(sa_column_kwargs={"comment": "手机号"}, max_length=11, nullable=True, unique=False)
email: Optional[str] = Field(sa_column_kwargs={"comment": "邮箱"}, max_length=50, nullable=True)
is_active: bool = Field(default=True)
role_links: List["UserRoleLink"] = Relationship(
back_populates="user",
sa_relationship_kwargs={"cascade": "all, delete-orphan"}
)
items: List["Item"] = Relationship(back_populates="owner") DescriptionIn my provided example, there is an Item model and a User model, which belong to different model files. The User model can own multiple Item instances (a one-to-many relationship), and the Relationship function is used to represent their relationship. The Item class calls the User model, and the User class calls the Item model, leading to a circular import issue. How should this issue be handled? Or is it a problem with my project structure? I want to separate them for better maintainability. The error message is as follows: Operating SystemWindows Operating System DetailsNo response SQLModel Version0.0.18 Python Version3.10 Additional ContextNo response |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
This is in the documentation on splitting your code into multiple files. You are doing the correct thing by type hinting with quotes inside your owner: Optional["User"] = Relationship(back_populates="items") Since you are quoting your type hint, you don't need the import at that file when running it. However, it's nice to have the import to get the auto completion in your editor :) This is what the documentation suggests, you should import
Your code would look like: from typing import TYPE_CHECKING
if TYPE_CHECKING:
from apps.auth.model import User
class Item(BaseModel, table=True):
__tablename__ = "items"
__table_args__ = ({"comment": "Item Table"})
title: str = Field(sa_column_kwargs={"comment": "标题"}, max_length=50, nullable=False)
description: Optional[str] = Field(sa_column_kwargs={"comment": "描述"}, max_length=255, nullable=True)
owner_id: int = Field(default=None, foreign_key="auth_users.id", nullable=False)
owner: Optional["User"] = Relationship(back_populates="items") Now in your from typing import TYPE_CHECKING # not necessary, but to be safe
if TYPE_CHECKING:
from apps.item.model import Item
from apps.user_role.model import UserRoleLink
class User(BaseModel, table=True):
__tablename__ = "auth_users"
__table_args__ = ({"comment": "User Table"})
username: str = Field(sa_column_kwargs={"comment": "用户名"}, max_length=50, index=True, nullable=True, unique=True)
hashed_password: str = Field(sa_column_kwargs={"comment": "密码"}, max_length=200, nullable=False)
avatar: Optional[str] = Field(sa_column_kwargs={"comment": "头像"}, max_length=200, nullable=True)
nickname: Optional[str] = Field(sa_column_kwargs={"comment": "昵称"}, max_length=50, nullable=True)
phone: Optional[str] = Field(sa_column_kwargs={"comment": "手机号"}, max_length=11, nullable=True, unique=False)
email: Optional[str] = Field(sa_column_kwargs={"comment": "邮箱"}, max_length=50, nullable=True)
is_active: bool = Field(default=True)
role_links: List["UserRoleLink"] = Relationship(
back_populates="user",
sa_relationship_kwargs={"cascade": "all, delete-orphan"}
)
items: List["Item"] = Relationship(back_populates="owner") |
Beta Was this translation helpful? Give feedback.
This is in the documentation on splitting your code into multiple files.
You are doing the correct thing by type hinting with quotes inside your
apps/item/model.py
file:Since you are quoting your type hint, you don't need the import at that file when running it. However, it's nice to have the import to get the auto completion in your editor :)
This is what the documentation suggests, you should import
TYPE_CHECKING
from thetyping
module.