Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQLAlchemy how to use a "fully module-qualified path"?

I'm contributing to a project that is using sqlalchemy. This project has a model.py file where they define all their classes, for example Foobar(BASE). Now, I've created another module mymodel.py where I need to extend some of those classes. So for example, in mymodule.py I have Foobar(model.Foobar) which I use to extend the parent class with new properties and functions. The problem is that when using either of those classes, I get this error from sqlalchemy: sqlalchemy.exc.InvalidRequestError: Multiple classes found for path "Foobar" in the registry of this declarative base. Please use a fully module-qualified path.. My question then is, how can I fix this error without renaming my classes? Since they are defined in a different module, how do I use a "fully module-qualified path"?

like image 895
user15399439 Avatar asked Sep 19 '25 00:09

user15399439


1 Answers

Faced the same issue, and also struggled to understand what the error is referring to by "fully module-qualified path" or where should I make the change.

After some trial and error, the key insight for me was that it has to do with SQLAlchemy relationships. Furthermore, in my case it also had to do with having the same table name in different schemas (I was using Postgres).

Simplified scenario that triggered the error:

# database/models/family_1.py

from database import MyOneAndOnlyBase
...

class Parent(MyOneAndOnlyBase):
    __tablename__ = "parent"
    id = Column(Integer, primary_key=True)
    children = relationship("Child")
    __table_args__ = {"schema": "family_1"}


class Child(MyOneAndOnlyBase):
    __tablename__ = "child"
    id = Column(Integer, primary_key=True)
    __table_args__ = {"schema": "family_1"}
# database/models/family_2.py

from database import MyOneAndOnlyBase
...

class Parent(MyOneAndOnlyBase):
    __tablename__ = "parent"
    id = Column(Integer, primary_key=True)
    children = relationship("Child")
    __table_args__ = {"schema": "family_2"}


class Child(MyOneAndOnlyBase):
    __tablename__ = "child"
    id = Column(Integer, primary_key=True)
    __table_args__ = {"schema": "family_2"}

And the way to fix it using a fully module-qualified path:

# database/models/family_1.py

from database import MyOneAndOnlyBase
...

class Parent(MyOneAndOnlyBase):
    __tablename__ = "parent"
    id = Column(Integer, primary_key=True)
    children = relationship("database.models.family_1.Child")
    __table_args__ = {"schema": "family_1"}



class Child(MyOneAndOnlyBase):
    __tablename__ = "child"
    id = Column(Integer, primary_key=True)
    __table_args__ = {"schema": "family_1"}
# database/models/family_2.py

from database import MyOneAndOnlyBase
...

class Parent(MyOneAndOnlyBase):
    __tablename__ = "parent"
    id = Column(Integer, primary_key=True)
    children = relationship("database.models.family_2.Child")
    __table_args__ = {"schema": "family_2"}



class Child(MyOneAndOnlyBase):
    __tablename__ = "child"
    id = Column(Integer, primary_key=True)
    __table_args__ = {"schema": "family_2"}
like image 83
swimmer Avatar answered Sep 21 '25 18:09

swimmer