Как построить отношения «многие ко многим» с помощью SQLAlchemy: хороший пример - PullRequest
13 голосов
/ 22 апреля 2011

Я прочитал документацию и руководство по 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)

Моя таблица сопоставления (определенаперед двумя другими в коде):

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 Ответ

13 голосов
/ 02 мая 2014

Из комментариев я вижу, что вы нашли ответ.Но документация по 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')
...