SQLAlchemy 使用关联配置与自我的多对多关系

Posted

技术标签:

【中文标题】SQLAlchemy 使用关联配置与自我的多对多关系【英文标题】:SQLAlchemy configuring many-to-many relationship to self using Association 【发布时间】:2011-08-31 18:05:52 【问题描述】:

我在配置与模型本身的多对多关系时遇到问题。当我使用normal 关系配置时,我可以配置自多对多关系,即不使用关联对象。

在这种情况下,我必须在多对多表本身中记录一些额外信息,因此我尝试使用关联对象 (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)

这种方法行不通。我试过删除 'secondaryjoin' 关键字,但它不起作用。

非常感谢您就此事提供任何帮助或建议。

感谢您的阅读。

【问题讨论】:

【参考方案1】:

关联对象模式不是多对多关系的特殊化,而是一对多关系的特殊情况,其中您有一个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)

这意味着,要从某个页面p 访问“to”链接的额外列,您必须这样做:p.linked_to[0].extra_col1,或者要获取实际链接的页面,p.linked_to[0].page_to


顺便说一句,使用自动增量主键或(左/右)外键对作为关联中的主键通常是一个好主意,但在主键中同时使用两者几乎没有用处。结合这两种想法的另一种方法是使用自动增量整数作为主键中的唯一列,并在左/右外键列上具有额外的唯一约束。

【讨论】:

以上是关于SQLAlchemy 使用关联配置与自我的多对多关系的主要内容,如果未能解决你的问题,请参考以下文章

Flask SQLAlchemy 多对多插入重复条目

如何避免在 SQLAlchemy - python 的多对多关系表中添加重复项?

与 SQLAlchemy 中不同的其他对象、自身和属性的多对多关系

通过 SQLAlchemy 选择多个多对多关系

与关联对象在同一张表上的多对多关系

python中flask和sqlalchemy的多对多