炼金术复杂关系

2024-09-29 03:41:08 发布

您现在位置:Python中文网/ 问答频道 /正文

我有两个(网络)表:接口和连接(如下),其中连接连接两个接口。 我想在接口中创建一个关系,这将允许我获得某个接口的连接接口,但不知道如何在接口类中创建这个关系?你知道吗

是不是像Interfaces类中的neighbour = relationship('Interface', primaryjoin='???')? 我想我过不去了接口id将在条件字符串中出现两次—一次用于引用连接.a或.b的“this”接口,然后一次用于引用回“other”接口的.b或.a?你知道吗

class Interface(Base):
    __tablename__ = 'tbl_interface'
    __table_args__ = (
        Index('un_interface', 'name', unique=True),
    )

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

class Connection(Base):
    __tablename__ = 'tbl_connection'
    __table_args__ = (
    Index('un_connection', 'a', 'b', unique=True),
    )
    a = Column(Integer, ForeignKey('tbl_interface.id', ondelete='CASCADE'), primary_key=True)
    b = Column(Integer, ForeignKey('tbl_interface.id', ondelete='CASCADE'),     primary_key=True)
    intf_a = relationship('Interface', primaryjoin='Connection.a == Interface.id')
    intf_b = relationship('Interface', primaryjoin='Connection.b == Interface.id')

编辑: 我有这个工作:

tbl_connection = Table('tbl_connection', Base.metadata,
    Column('a', Integer, ForeignKey('tbl_interface.id', ondelete='CASCADE'), primary_key=True),
    Column('b', Integer, ForeignKey('tbl_interface.id', ondelete='CASCADE'), primary_key=True),
    CheckConstraint('a > b', name='a_over_b')
    )


class Interface(Base):
    __tablename__ = 'tbl_interface'
    __table_args__ = (
        Index('un_interface''name', unique=True),
    )

    id = Column(Integer, primary_key=True)
    name = Column(String(45), nullable=False)
    neighbor_interface = relationship('Interface', uselist=False,
                               secondary=tbl_connection,
                               primaryjoin=id == tbl_connection.c.a,
                               secondaryjoin=id == tbl_connection.c.b,
                               backref='whatever_questionmark'
                               )

我特别需要uselist=False,否则在插入连接记录时会出现以下错误:TypeError: Incompatible collection type: Interface is not list-like。 我在One to one self relationship in SQLAlchemy里发现的

这让我可以做到以下几点,真的很酷:)

    inta = Interface(name='inta')
    intb = Interface(name='intb')
    inta.neighbor_interface = intb
    ses.add(inta)
    ses.add(intb)
    ses.commit()
    inta_copy = ses.query(Interface).filter(Interface.name == 'inta').first()
    intb_copy = ses.query(Interface).filter(Interface.name == 'intb').first()
    print('a:{}, b:{}'.format(intfa.neighbor_interface.name, intfb.neighbor_interface.name))

但是,这对我没有帮助,因为只有两个接口中的一个能够正确地获取其相反的邻居。你知道吗


Tags: keynameidtruecolumnintegerconnectioninterface