最新消息:Welcome to the puzzle paradise for programmers! Here, a well-designed puzzle awaits you. From code logic puzzles to algorithmic challenges, each level is closely centered on the programmer's expertise and skills. Whether you're a novice programmer or an experienced tech guru, you'll find your own challenges on this site. In the process of solving puzzles, you can not only exercise your thinking skills, but also deepen your understanding and application of programming knowledge. Come to start this puzzle journey full of wisdom and challenges, with many programmers to compete with each other and show your programming wisdom! Translated with DeepL.com (free version)

python - Sqlalchemy: circular import while implementing foreign key in different files - Stack Overflow

matteradmin7PV0评论

so I got two files: auth.py and chats.py

The main goal: The two classes in two different files must be bound to each other using foreign key

The main problem: But to do this, foreign key requires me to import files. If I do so, I get into circular import, if I don't, then both classes dont recognize each other.

When I try to bind two classes with foreign key, I got stuck in circular import, since I am importing my classes in both files.

# auth.py:
from sqlalchemy import (
    create_engine,
    Column,
    Integer,
    BigInteger,
    String,
    Text,
    Boolean,
    DateTime,
    ForeignKey,
    Enum,
    Table,
    UniqueConstraint,
)
from sqlalchemy.orm import relationship, sessionmaker
from sqlalchemy.dialects.postgresql import UUID
import uuid

from src.settings import settings
from sqlalchemy.sql import func

from .legacy.base_model import BaseModel
from .chats import Admin, Group


class User(BaseModel):
    __tablename__ = "user"

    username = Column(String)
    first_name = Column(String) 
    last_name = Column(String)
    bio = Column(Text)
    avatar = Column(String)
    gender = Column(Boolean)    
    birthdate = Column(DateTime)
    email = Column(String, unique=True)
    password = Column(String)
    phone_number = Column(String)
    live_status = Column(Boolean)
    last_seen = Column(DateTime)
    language = Column(UUID(as_uuid=True), ForeignKey("locale.id"))

    admins = relationship("Admin", back_populates="user")
    groups = relationship("Group", back_populates="owner")


class Locale(BaseModel):
    __tablename__ = "locale"

    code = Column(String)       
# chats.py
from sqlalchemy import (
    create_engine,
    Column,
    Integer,
    BigInteger,
    String,
    Text,
    Boolean,
    DateTime,
    ForeignKey,
    Enum,
    Table,
    UniqueConstraint,
)
from sqlalchemy.orm import relationship, sessionmaker, declared_attr
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.sql import func
import uuid


from .legacy.base_model import BaseModel
from src.settings import settings
from .auth import User  # here is the main problem, I am importing User here, and 
                        # in auth.py file the Admin class below also was imported

class Admin(BaseModel):
    __tablename__ = "admins"

    chat_id = Column(UUID(as_uuid=True), ForeignKey("channel.id"))
    chat_type = Column(Enum("channel", "group", "direct", name="chat_type_enum"))
    user_id = Column(UUID(as_uuid=True), ForeignKey("user.id"))
    admin_name = Column(String)

    channel = relationship("Channel", back_populates="admins")



class Group(BaseModel):
    __tablename__ = "group"

    owner_id = Column(UUID(as_uuid=True), ForeignKey("user.id"))
    title = Column(String)
    code = Column(String)
    member_count = Column(BigInteger)
    description = Column(Text)
    avatar = Column(String)
    visibility = Column(Boolean)

    owner = relationship("User", back_populates="groups")


class Subscriber(BaseModel):
    __tablename__ = "subscribers"

    chat_id = Column(UUID(as_uuid=True), ForeignKey("channel.id"))
    user_id = Column(UUID(as_uuid=True), ForeignKey("user.id"))

    channel = relationship("Channel", back_populates="subscribers")


class Channel(BaseModel):
    __tablename__ = "channel"

    title = Column(String)
    description = Column(Text)
    code = Column(String)
    avatar = Column(String)
    member_count = Column(BigInteger)
    owner_id = Column(UUID(as_uuid=True), ForeignKey("user.id"))

    admins = relationship("Admin", back_populates="channel")
    subscribers = relationship("Subscriber", back_populates="channel")

and I also have BaseModel class which was bound to declarative base and gives some basic default columns for all of my tables:

from sqlalchemy import String, UUID, Column, DateTime, Boolean
from sqlalchemy.orm import mapped_column, Mapped
from sqlalchemy.sql import func
import uuid

from src.db.orm.config import SessionLocal
from src.db.orm.config import Base
from src.logger import logger


class BaseModel(Base):
    """
    This class serves as a base model for all other database models in the application.
    It provides common fields such as id, created_at, updated_at, and status.

    Attributes:
    - id (UUID): Unique identifier for each record.
    - created_at (DateTime): Timestamp indicating when the record was created.
    - updated_at (DateTime): Timestamp indicating when the record was last updated.
    """

    __abstract__ = True

    id = Column(UUID, default=uuid.uuid4, primary_key=True, nullable=False)
    created_at = Column(DateTime, nullable=True, default=func.now())
    updated_at = Column(
        DateTime, nullable=True, default=func.now(), onupdate=func.now()
    )

    def __repr__(self):
        raise NotImplementedError("Please implement the description of the table")
    

    def save(self):
        """Save the instance to the database."""
        try:
            session = SessionLocal()
            session.add(self)
            sessionmit()
            logger.info("Saved successfully")
            return self
        except Exception as e:
            session.rollback()
            raise e

But if I dont import them, they wont recognize each other. I am really wondering that do I have a chance to just assign it like I assign in django, like this: src.db.orm.auth.User inside the Admin class and vice versa.

Any advice or help is strongly appreciated.

I tried to import both files to each other, but got into circular import.

Post a comment

comment list (0)

  1. No comments so far