I have a database with tables named qs_dashboard
and profile
which are linked with an intermediate table named dashboard_permissions
. My issue is that when I try to add a relationship in my SQLAlchemy models from Dashboard
to Profile
via dashboard_permissions.profile_id
, I get the following error whether or not my code is testing the new relationship:
NameError: Module 'qs_dashboard_permission' has no mapped classes registered under the name '_sa_instance_state'
I have no idea what _sa_instance_state
refers to.
The stack trace points to the first time that a query is evaluated. Ex:
query = select(Profile).filter(Profile.uuid == 'some uuid')
profile: Profile = session.scalars(query).first()
The relevant parts of my schema are as follows:
Dashboard.profiles
including using the overlaps and back_populates parameters, but I keep getting the same error message.Dashboard.profiles
, all of my unit tests start working again besides the ones that rely on Dasboard.profiles
.dashboard.py
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from .profile import Profile
from .dashboard_permission import DashboardPermissions
else:
Profile = 'Profile'
DashboardPermissions = 'DashboardPermissions'
from . import Base
from sqlalchemy import (
String,
)
from sqlalchemy.orm import (
mapped_column,
relationship,
Mapped,
DynamicMapped,
)
class Dashboard(Base):
__tablename__ = 'dashboard'
id: Mapped[str] = mapped_column(String, primary_key = True)
profiles: DynamicMapped[Profile] = relationship(Profile,
lazy = 'dynamic',
secondary = 'dashboard_permission',
foreign_keys = 'DashboardPermissions.profile_id',
#overlaps = 'qs_dashboard_permissions',
#back_populates = 'dashboards',
)
profile.py
from sqlalchemy import Integer
from sqlalchemy.orm import (
mapped_column,
Mapped,
)
class Profile(Base):
__tablename__ = 'profile'
id: Mapped[Integer] = mapped_column(Integer, primary_key = True, index = True, unique = True)
dashboard_permissions.py
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from .profile import Profile
from .dashboard import Dashboard
else:
Profile = 'Profile'
Dashboard = 'Dashboard'
from . import Base
from sqlalchemy import (
ForeignKey,
Integer,
String,
)
from sqlalchemy.orm import (
relationship,
mapped_column,
Mapped,
)
from sqlalchemy import (
DateTime,
)
from .enums.qs_permission import QsPermission
import boto3
cognito = boto3.client('cognito-idp')
class DashboardPermissions(Base):
__tablename__ = 'dashboard_permissions'
profile_id: Mapped[int] = mapped_column(Integer, ForeignKey('profile.id'), primary_key = True)
profile: Mapped[Profile] = relationship(Profile, foreign_keys = [profile_id], back_populates = 'dashboard_permissions', overlaps='dashboard_permissions')
dashboard_id: Mapped[str] = mapped_column(String, ForeignKey('dashboard.id'), primary_key = True)
dashboard: Mapped[Dashboard] = relationship(Dashboard, foreign_keys = [dashboard_id], overlaps='dashboard_permissions')
shared_by_id: Mapped[int] = mapped_column(Integer, ForeignKey('profile.id'))
shared_by: Mapped[Profile] = relationship(Profile, foreign_keys = [shared_by_id], back_populates = 'dashboard_permissions_shared', overlaps='dashboard_permissions')
My issue was that I had a typo in the secondary table name. In this example, "dashboard_permission" should have been "dashboard_permissions".