3
0

sqlalchemy.exc.InvalidRequestError: One or more mappers failed to initialize - can't proceed with initialization of other mappers.の対処法

Posted at

エラー全文

sqlalchemy.exc.InvalidRequestError: One or more mappers failed to initialize - can't proceed with initialization of other mappers. Triggering mapper: 'Mapper[ProjectUser(projects_users)]'. Original exception was: When initializing mapper Mapper[ProjectUser(projects_users)], expression 'User' failed to locate a name ('User'). If this is a class name, consider adding this relationship() to the class after both dependent classes have been defined.

多対多モデルの定義

はじめ、下記のようにモデルを設定していました。

user.py
from sqlalchemy import Column, String
from sqlalchemy.orm import relationship

from app.db.base_class import Base
from app.models.project_user import ProjectUser


class User(Base):
    __tablename__ = "users"
    name = Column(String(255), nullable=False)

    projects = relationship(
        "Project",
        secondary=ProjectUser.__tablename__,
        back_populates="users",
    )
    project_user = relationship("ProjectUser")
project.py
from sqlalchemy import Column, String
from sqlalchemy.orm import relationship

from app.db.base_class import Base
from app.models.project_user import ProjectUser


class Project(Base):
    __tablename__ = "projects"
    title = Column(String(255), default="", nullable=False)
    users = relationship(
        "User",
        secondary=ProjectUser.__tablename__,
        back_populates="projects",
    )
    project_user = relationship("ProjectUser")
project_user.py
from sqlalchemy import Column, ForeignKey, Integer
from sqlalchemy.orm import relationship

from app.db.base_class import Base


class ProjectUser(Base):
    __tablename__ = "projects_users"
    project_id = Column(
        Integer, ForeignKey("projects.id", ondelete="RESTRICT"), nullable=False
    )
    user_id = Column(
        Integer, ForeignKey("users.id", ondelete="RESTRICT"), nullable=False
    )

    user = relationship("User")
    project = relationship("Project")

原因

エラー文を読み込むと、「Userという文字列に該当するモデルクラスが見つからない」と言われていることがわかる。
SQLAlchemyのrelationshipを使用する際には、モデルを読み込む順序は内部で決まっているが、まだUserモデルを読み込んでいないにもかかわらず、Projectモデルでリレーションを張ろうとしても失敗してしまう、ということを示している。

解決方法

Projectモデルを設定する前に、Userを読み込んであげればよい。
# noqaを記述しているのは、Linterエラーに引っかかるのを防ぐため。)

project.py
from sqlalchemy import Column, String
from sqlalchemy.orm import relationship

from app.db.base_class import Base
from app.models.project_user import ProjectUser

# from app.models.feature import Feature  # noqa # 追加した部分


class Project(Base):
    __tablename__ = "projects"
    title = Column(String(255), default="", nullable=False)
    users = relationship(
        "User",
        secondary=ProjectUser.__tablename__,
        back_populates="projects",
    )
    project_user = relationship("ProjectUser")
3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0