SQLAlchemy, настраивающий отношение «многие ко многим» к самому себе с использованием ассоциации - PullRequest
3 голосов
/ 31 августа 2011

У меня проблемы с настройкой отношения «многие ко многим» с самой моделью.Я могу настроить отношение «сам ко многим ко многим», когда использую нормальную конфигурацию отношений, то есть такую, которая не использует объект Association.

В этом сценарии мне необходимо записать некоторую дополнительную информацию всама таблица «многие ко многим», поэтому я пытаюсь реализовать взаимосвязь с использованием объекта Association (PageLink).

Вот модели.

class PageLink(Base):
    '''
    Association table.
    '''
    __tablename__ = 'page_links'

    id = Column(Integer,primary_key=True)
    page_from = Column(Integer,ForeignKey('page.id'),primary_key=True)
    page_to = Column(Integer,ForeignKey('page.id'),primary_key=True)
    extra_col1 = Column(String(256),nullable=False)

class Page(Base):
    '''
    main table
    '''

    __tablename__ = 'page'

    id = Column(Integer,primary_key=True)
    name = Column(String(56),nullable=False)

    linked = relationship('PageLinks',backref='parent_page',
                          primaryjoin=id==PageLink.page_from,
                          secondaryjoin=id==PageLink.page_to)

Этот подход не работает.Я попытался удалить ключевое слово "secondjoin", но оно не сработало.

Буду очень признателен за любую помощь или совет по этому вопросу.

Спасибо, что прочитали.

1 Ответ

5 голосов
/ 31 августа 2011

Шаблон объекта ассоциации - это не специализация отношения «многие ко многим», а скорее частный случай отношений «один ко многим», когда у вас есть left_table - «Многие ко одному» - association_table -Один-ко-многим - right_table настроен.Короче говоря, вам нужно два отношения, ни у одного из которых не должно быть secondary / secondaryjoin.

class PageLink(Base):
    '''
    Association table.
    '''
    __tablename__ = 'page_links'

    id = Column(Integer,primary_key=True)
    page_from = Column(Integer,ForeignKey('page.id'),primary_key=True)
    page_to = Column(Integer,ForeignKey('page.id'),primary_key=True)
    extra_col1 = Column(String(256),nullable=False)

class Page(Base):
    '''
    main table
    '''

    __tablename__ = 'page'

    id = Column(Integer,primary_key=True)
    name = Column(String(56),nullable=False)

    linked_to = relationship('PageLinks',backref='parent_page',
                             primaryjoin=id==PageLink.page_from)
    linked_from = relationship('PageLinks',backref='child_page',
                               primaryjoin=id==PageLink.page_to)

, что означает доступ к дополнительному столбцу для 'to'ссылки с какой-то страницы p, вам нужно сделать: p.linked_to[0].extra_col1, или чтобы получить реальную ссылку на страницу, p.linked_to[0].page_to


В качестве отступления, часто хорошая идея использовать либоавтоинкремент первичного ключа или (левый / правый) пара внешних ключей в качестве первичного ключа в ассоциациях, но почти никогда не полезно иметь оба в первичном ключе.Альтернативой, которая объединяет обе идеи, является использование целого числа автоинкремента в качестве единственного столбца в первичном ключе и наличие дополнительного уникального ограничения на левый / правый столбцы внешнего ключа.

...