having a trouble with ManyToMany relationship configuration - "sqlalchemy.exc.InvalidRequestError" [SOLVED]

22 Views Asked by At

I am new to SQLAlchemy and have some errors with ManyToMany relationship configuration.

Before I paste my code here, I would like to give a short description: I have a model UserORM and ProjectORM, they are related as many-to-many. Also, I created an association table UserProjectORM and the table has some additional fields.

So, here is ProjectORM:

class ProjectORM(AbstractModel):
    __tablename__ = "projects"

    status: Mapped[EnumStatus]
    title: Mapped[str] = mapped_column(String(255), unique=True)
    description: Mapped[str | None]

    category_id: Mapped[int] = mapped_column(ForeignKey("categories.id"))
    category: Mapped[CategoryORM] = relationship(back_populates="projects")

    users: Mapped[list["UserProjectORM"]] = relationship(back_populates="projects")
    resources: Mapped[list["ResourceORM"]] = relationship(back_populates="project")

    time_created: Mapped[time_created]

Here is UserORM placed in another file:

class UserORM(AbstractModel):
    __tablename__ = "users"

    username: Mapped[str] = mapped_column(String(35), unique=True)
    age: Mapped[str] = mapped_column(String(3), nullable=True)
    email: Mapped[str] = mapped_column(String(155), unique=True)

    surname: Mapped[str] = mapped_column(String(100))
    firstname: Mapped[str] = mapped_column(String(100))
    patronymic: Mapped[str] = mapped_column(String(100), nullable=True)
    about: Mapped[str] = mapped_column(nullable=True)
    file_path: Mapped[str] = mapped_column(nullable=True)

    hashed_password: Mapped[str] = mapped_column(String(125))
    is_active: Mapped[bool] = mapped_column(default=False)
    time_created: Mapped[time_created]

    tokens: Mapped[list["TokenORM"]] = relationship(back_populates="user")
    projects: Mapped[list["project.UserProjectORM"]] = relationship(back_populates="users")

And association table UserProjectORM with some extra fields:

class UserProjectORM(AbstractModel):
    __tablename__ = "users_projects"

    user_id: Mapped[int] = mapped_column(ForeignKey("users.id"), primary_key=True)
    project_id: Mapped[int] = mapped_column(ForeignKey("projects.id"), primary_key=True)
    user: Mapped["user.UserORM"] = relationship(back_populates="projects")
    project: Mapped["ProjectORM"] = relationship(back_populates="users")

    is_author: Mapped[bool] = mapped_column(Boolean, default=False)
    datatime_joined: Mapped[time_created]

time_created field is imported from another file:

time_created = Annotated[
    datetime.datetime,
    mapped_column(DateTime(timezone=True), server_default=func.now()),
]

And here is my error I have:

sqlalchemy.exc.InvalidRequestError: One or more mappers failed to initialize - can't proceed with initialization of other mappers. Triggering mapper: 'Mapper[ProjectORM(projects)]'. Original exception was: Mapper 'Mapper[UserProjectORM(users_projects)]' has no property 'projects'.  If this property was indicated from other mappers or configure events, ensure registry.configure() has been called.


/usr/local/lib/python3.11/site-packages/sqlalchemy/orm/mapper.py:4240: InvalidRequestError
1

There are 1 best solutions below

0
Mihail Bury On

The answer appeared to be pretty simple.

The problem was in these lines:

projects: Mapped[list["project.UserProjectORM"]] = relationship(back_populates="users")
users: Mapped[list["UserProjectORM"]] = relationship(back_populates="projects")

So I changed it to:

projects: Mapped[list["project.UserProjectORM"]] = relationship(back_populates="user")
users: Mapped[list["UserProjectORM"]] = relationship(back_populates="project")

The reason was that SQLAlchemy tried to find non-existent projects/users property of the Mapper. However, the correct properties was project and user