Как построить отношения "многие ко многим" с помощью SQLAlchemy: хороший пример
Я прочитал документацию SQLAlchemy и учебник о создании отношения "многие ко многим", но я не мог понять, как это сделать правильно, когда таблица ассоциации содержит больше двух внешних ключей.
У меня есть таблица элементов, и каждый элемент имеет много деталей. Детали могут быть одинаковыми для многих элементов, поэтому между элементами и деталями существует соотношение "многие-ко-многим".
У меня есть следующее:
class Item(Base):
__tablename__ = 'Item'
id = Column(Integer, primary_key=True)
name = Column(String(255))
description = Column(Text)
class Detail(Base):
__tablename__ = 'Detail'
id = Column(Integer, primary_key=True)
name = Column(String)
value = Column(String)
Моя таблица связей (она определена перед другими 2 в коде):
class ItemDetail(Base):
__tablename__ = 'ItemDetail'
id = Column(Integer, primary_key=True)
itemId = Column(Integer, ForeignKey('Item.id'))
detailId = Column(Integer, ForeignKey('Detail.id'))
endDate = Column(Date)
В документации говорится, что мне нужно использовать "объект ассоциации". Я не мог понять, как правильно его использовать, поскольку он смешивает декларативные формы с картографом, и примеры, похоже, не полны. Я добавил строку:
details = relation(ItemDetail)
как член класса Item и строки:
itemDetail = relation('Detail')
как член таблицы ассоциаций, как описано в документации.
когда я делаю item = session.query(Item).first(), item.details - это не список объектов Detail, а список объектов ItemDetail.
Как я могу правильно получить детали объектов Item, т.е. item.details должен быть списком объектов Detail?
Ответы
Ответ 1
Из комментариев, которые я вижу, вы нашли ответ. Но документация SQLAlchemy довольно подавляющая для "нового пользователя", и я боролся с тем же вопросом. Поэтому для справок в будущем:
ItemDetail = Table('ItemDetail',
Column('id', Integer, primary_key=True),
Column('itemId', Integer, ForeignKey('Item.id')),
Column('detailId', Integer, ForeignKey('Detail.id')),
Column('endDate', Date))
class Item(Base):
__tablename__ = 'Item'
id = Column(Integer, primary_key=True)
name = Column(String(255))
description = Column(Text)
details = relationship('Detail', secondary=ItemDetail, backref='Item')
class Detail(Base):
__tablename__ = 'Detail'
id = Column(Integer, primary_key=True)
name = Column(String)
value = Column(String)
items = relationship('Item', secondary=ItemDetail, backref='Detail')