简体   繁体   English

自引用多对多关系与 SQLAlchemy 中的关联 object

[英]Self-referencing many-to-many relationship with an association object in SQLAlchemy

I've found examples for a self-referencing many-to-many relationship with an association table.我找到了与关联表的自引用多对多关系的示例。 How can I achieve the same using an association object?如何使用关联 object 实现相同的目标?

The code below is based on: How can I achieve a self-referencing many-to-many relationship on the SQLAlchemy ORM back referencing to the same attribute?下面的代码基于: 如何在 SQLAlchemy ORM 上实现对同一属性的自引用多对多关系?

from sqlalchemy import Table, Column, Integer, ForeignKey
from db.common import Base
from sqlalchemy.orm import relationship

M2M = Table('m2m',
            Base.metadata,
            Column('entity_parent_id', 
                   Integer,
                   ForeignKey('entity.id'),
                   primary_key=True),
            Column('entity_child_id',
                   Integer,
                   ForeignKey('entity.id'), 
                   primary_key=True),
)


class Entity(Base):
    __tablename__ = 'entity'

    id = Column(Integer, primary_key=True)

    entity_childs = relationship("Entity",
                                    secondary=M2M,
                                    primaryjoin="Enity.id==m2m.c.entity_parent_id",
                                    secondaryjoin="Enity.id==m2m.c.entity_child_id",
                                    )

    entity_parents = relationship("Entity",
                                     secondary=M2M,
                                     primaryjoin="Enity.id==m2m.c.entity_child_id",
                                     secondaryjoin="Enity.id==m2m.c.entity_parent_id",
                                     )

The following approach uses an association object instead of an association table to get a self-referencing many-to-many relationship:以下方法使用关联 object 而不是关联表来获得自引用多对多关系:

from sqlalchemy import Column, Integer, ForeignKey, create_engine, String
from sqlalchemy.orm import relationship, sessionmaker
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class EntityAssociation(Base):
    __tablename__ = 'entity_association'

    entity_parent_id = Column(Integer, ForeignKey('entity.id'), primary_key=True)
    entity_child_id = Column(Integer, ForeignKey('entity.id'), primary_key=True)

class Entity(Base):
    __tablename__ = 'entity'

    id = Column(Integer, primary_key=True)
    name = Column(String)

    entity_childs = relationship('Entity',
                                 secondary='entity_association',
                                 primaryjoin=id==EntityAssociation.entity_parent_id,
                                 secondaryjoin=id==EntityAssociation.entity_child_id,
                                 backref='childs')

    entity_parents = relationship('Entity',
                                  secondary='entity_association',
                                  primaryjoin=id==EntityAssociation.entity_child_id,
                                  secondaryjoin=id==EntityAssociation.entity_parent_id,
                                  backref='parents')

    def __repr__(self):
        return f'<Entity(name={self.name})>'

if __name__ == '__main__':
    engine = create_engine('sqlite://')
    Base.metadata.create_all(engine)
    Session = sessionmaker(engine)

    db = Session()

    parent1 = Entity(name='parent1')
    parent2 = Entity(name='parent2')
    child1 = Entity(name='child1')
    child2 = Entity(name='child2')

    parent1.entity_childs = [child1, child2]
    parent2.entity_childs = [child2]

    db.add(parent1)
    db.add(parent2)
    db.add(child1)
    db.add(child2)
    db.commit()

    entities = db.query(Entity).all()
    for entity in entities:
        print(entity)
        print('   Parent: ', entity.entity_parents)
        print('   Childs: ', entity.entity_childs)
        print()

This will have the following result:这将产生以下结果:

<Entity(name=parent1)>
   Parent:  []
   Childs:  [<Entity(name=child1)>, <Entity(name=child2)>]

<Entity(name=child1)>
   Parent:  [<Entity(name=parent1)>]
   Childs:  []

<Entity(name=child2)>
   Parent:  [<Entity(name=parent1)>, <Entity(name=parent2)>]
   Childs:  []

<Entity(name=parent2)>
   Parent:  []
   Childs:  [<Entity(name=child2)>]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 自引用多对多关系与关联 object 中的额外列 - Self referencing many-to-many relationship with extra column in association object 如何在 SQLAlchemy ORM 上实现自引用多对多关系,反向引用相同的属性? - How can I achieve a self-referencing many-to-many relationship on the SQLAlchemy ORM back referencing to the same attribute? SQLAlchemy使用Association配置与self的多对多关系 - SQLAlchemy configuring many-to-many relationship to self using Association 通过SqlAlchemy中的关联对象实现多对多,自引用,非对称关系(推特模型) - Many-to-many, self-referential, non-symmetrical relationship (twitter model) via Association Object in SqlAlchemy 一对多自我引用关系SQLAlchemy - One to Many Self-Referencing relation SQLAlchemy 多对多关联表上的SQLAlchemy关系 - SQLAlchemy relationship on many-to-many association table 如何在peewee中创建自引用多对多字段? - How to create self-referencing many-to-many field in peewee? 如何在SQLAlchemy中与关联对象(没有关联代理)建立多对多关系? - How can I access extra columns in SQLAlchemy a many-to-many relationship with an association object (without an association proxy)? SqlAlchemy与关联对象的多对多关系问题 - SqlAlchemy Many to Many relationship with an association object issues SQLAlchemy多对多关系和关联对象 - SQLAlchemy many to many relationship & Association object
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM