自引用关系包括关系属性

时间:2014-08-20 16:42:43

标签: python entity-framework sqlalchemy self-reference

情况

我有自我引用的多对多关系(几乎与同一标题的sqlalchemy手册条目相同)。此关系由表entity_weights控制。这段代码有效!

问题

如何在代表表格列Entity的班级entity_weights.weight中添加属性。可以说该属性将被称为Entity.child_weightsEntity.child_entitiesEntity.child_weights的排名必须相同。

entity_weights = Table('entity_weights', Base.metadata,
    Column('id',Integer, primary_key=True),
    Column('parent_entity_id',Integer, ForeignKey('entity.id')),
    Column('entity_id',Integer, ForeignKey('entity.id')),
    Column('weight',Float))


class Entity(Base):
    __tablename__ = 'entity'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    domicile_id = Column(Integer, ForeignKey('domicile.id'))
    entity_type = Column('type',Enum('asset','institution','model'))
    source_table_id = Column(Integer)
    child_entities = relationship('Entity',
                        secondary=entity_weights,
                        primaryjoin=id==entity_weights.c.parent_entity_id,
                        secondaryjoin=id==entity_weights.c.entity_id,
                        backref='parent_entity_id'
                        )

1 个答案:

答案 0 :(得分:1)

我在此方案中找到的最干净的解决方案是通过在child_entities上添加entity_weights作为一对多关系来解除Entity关系并使用association proxy代理weight值以及多对多关系的远程端:

class EntityWeight(Base):
    __tablename__ = "entity_weights"
    id = Column(Integer, primary_key=True)
    parent_entity_id = Column(Integer, ForeignKey('entity.id'))
    entity_id = Column(Integer, ForeignKey('entity.id'))
    weight = Column(Float)
    entity = relationship("Entity", primaryjoin=lambda: EntityWeight.entity_id == Entity.id)

class Entity(Base):
    ...
    _child_weights = relationship(EntityWeight, primaryjoin=id == EntityWeight.parent_entity_id)
    child_weights = association_proxy("_child_weights", "weight")
    child_entities = association_proxy("_child_weights", "entity")
相关问题