SQLAlchemy как отразить отношения «многие ко многим»

#sql #sqlalchemy

Вопрос:

У меня есть две существующие таблицы со связью «многие ко многим». Я пытаюсь выполнить запрос из этих таблиц, но, похоже, я не могу отразить их соотношение «многие ко многим».

Допустим, у меня есть две модели с такой справочной таблицей

 from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import declarative_base, relationship
from sqlalchemy import Table

Base = declarative_base()

family_tree = Table(
    "family_tree",
     Base.metadata,
     Column("brother_id", Integer, ForeignKey("brother.id"), primary_key=True),
     Column("sister_id", Integer, ForeignKey("sister.id"), primary_key=True),
)

class Sister(Base):
    __tablename__ = 'sister'
    id = Column(Integer, autoincrement=True, primary_key=True)
    brothers = relationship("Brother", secondary=family_tree, back_populates="sisters", 
    uselist=True)

class Brother(Base):
    __tablename__ = 'brother'
    id = Column(Integer, autoincrement=True, primary_key=True)
    sisters = relationship("Sister", secondary=family_tree, back_populates="brothers", 
    uselist=True)
 

и я заполнил все три таблицы. Теперь я хочу получить доступ к brothers информации о данной Sister записи таблицы.

Я попытался получить доступ к sister таблице следующим образом

 class SisterInspector(Base):
     __tablename__ = 'sister'
     __table_args__ = {'autoload': True}

session.query(SisterInspector).first()
 

который прекрасно работает с

 session.query(SisterInspector.id)
 

но бросает AttributeError , когда пытается

 session.query(SisterInspector.brothers)
>>> AttributeError: 'Sister' object has no attribute 'brothers'
 

Я пытался получить доступ к своим таблицам этим альтернативным способом

 from sqlalchemy.schema import Table, MetaData
meta = MetaData()
meta.reflect(bind=engine)
foo = Table('sister', meta, autoload_with=engine)
print(foo.columns)
>>>> ImmutableColumnCollection(sister.id)
 

Я понимаю, что связь не определяется как столбец, но

 foo
>>>> Table('sister',...)
 

также не упоминается об указанных отношениях. Как мне получить отношение «многие ко многим» из моей базы данных?

Ответ №1:

Я не уверен, что класс SisterInspector делает для вас, моя реализация SQLAlchemy не использует подобный специальный класс инспектора-и мне интересно, не является ли причиной проблемы тот факт, что он использует то же имя таблицы, что и ваш класс Sisters.

Можете ли вы дать нам результат чего-то вроде

first_sister = сеанс.запрос(сестра).первый()

печать(first_sister.brothers)