Почему появляется ошибка relationship expects a class or a mapper argument в SQLAlchemy?
Создал таблицы для базы данных с помощью sqlalchemy.
class Base(DeclarativeBase):
pass
class UserPlaylistLink(Base):
__tablename__ = "user_playlist_link"
user_id: Mapped[UUID] = mapped_column(ForeignKey("user.id"), primary_key=True)
playlist_id: Mapped[UUID] = mapped_column(ForeignKey("playlist.id"), primary_key=True)
status: Mapped[PlaylistStatus] = mapped_column(Enum(PlaylistStatus), nullable=False)
class User(Base):
__tablename__ = "user"
id: Mapped[UUID] = mapped_column(primary_key=True)
mail: Mapped[str]
playlists: Mapped[list["Playlist"]] = relationship("playlist", secondary="UserPlaylistLink", back_populates="users")
class Playlist(Base):
__tablename__ = "playlist"
id: Mapped[UUID] = mapped_column(primary_key=True)
name: Mapped[str]
author_id: Mapped[UUID] = mapped_column(nullable=False)
users: Mapped[list["User"]] = relationship("user", secondary="UserPlaylistLink", back_populates="playlists")
Но когда пытался протестировать добавление пользователя в базу стала появляться ошибка:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <Relationship at 0x1271ff24eb0; placelists>
_RelationshipProperty__argument = None
@util.preload_module("sqlalchemy.orm.mapper")
def _setup_entity(self, __argument: Any = None) -> None:
if "entity" in self.__dict__:
return
mapperlib = util.preloaded.orm_mapper
if __argument:
argument = __argument
else:
argument = self.argument
resolved_argument: _ExternalEntityType[Any]
if isinstance(argument, str):
# we might want to cleanup clsregistry API to make this
# more straightforward
resolved_argument = cast(
"_ExternalEntityType[Any]",
self._clsregistry_resolve_name(argument)(),
)
elif callable(argument) and not isinstance(
argument, (type, mapperlib.Mapper)
):
resolved_argument = argument()
else:
resolved_argument = argument
entity: _InternalEntityType[Any]
if isinstance(resolved_argument, type):
entity = class_mapper(resolved_argument, configure=False)
else:
try:
entity = inspect(resolved_argument)
except sa_exc.NoInspectionAvailable:
entity = None # type: ignore
if not hasattr(entity, "mapper"):
> raise sa_exc.ArgumentError(
"relationship '%s' expects "
"a class or a mapper argument (received: %s)"
% (self.key, type(resolved_argument))
)
E sqlalchemy.exc.ArgumentError: relationship 'playlists' expects a class or a mapper argument (received: <class 'sqlalchemy.sql.schema.Table'>)
Можете подсказать, в чем проблема? Может я как-то неправильно понял как работает relationship?
Если заменить строку в relationship(secondary=...) на сам класс, вместо строки, то появляется предупреждение в IDE: Expected type 'FromClause | str | () -> FromClause | None', got 'Type[UserPlaylistLink]' instead.
Ответы (1 шт):
Автор решения: Maksim Alekseev
→ Ссылка
В строке ниже, передано название таблицы "playlist"
playlists: Mapped[list["Playlist"]] = relationship("playlist", secondary="UserPlaylistLink", back_populates="users")
нужно передать название класса "Playlist"
playlists: Mapped[list["Playlist"]] = relationship("Playlist", secondary="UserPlaylistLink", back_populates="users")