SQLAlchemy复杂关系

时间:2018-08-16 09:05:35

标签: python sqlalchemy foreign-keys relational-database

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

在Interfaces类中是否会像neighbour = relationship('Interface', primaryjoin='???')一样? 我想我无法超越Interface.id在条件字符串中出现两次的情况,一次是“ this”接口引用connections.a或.b,然后是.b或.a引用“ other”界面?

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))

但是,这对我没有帮助,因为如果两个接口正确地能够获取其相对的邻居,则只有一个。

0 个答案:

没有答案