三个表之间的SQLAlchemy关系

2024-04-20 10:40:31 发布

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

我有三个表:设备、插槽、端口。在

  1. 设备将有几个插槽
  2. 插槽将有多个端口,但属于一个设备
  3. 端口属于单个插槽

根据我的经验,这表现为:

  1. 设备(一对多)插槽
  2. 插槽(一对多)端口

我试图在我的设备类中设置一个关系,它将给我所有相关的端口对象(不管插槽是什么)。我想不通。关联表看起来很接近,但我无法从周围的例子中看出如何做我想要的。在

class Devices(Base):
  __tablename__ = 'devices'
  __table_args__ = {
    'mysql_engine' : 'MyISAM',
    'mysql_charset': 'latin1'
  }

  did             = Column( INTEGER, primary_key=True )
  hostname        = Column( VARCHAR(255) )
  site            = Column( INTEGER, ForeignKey('site.sid'), default=0 )
  model           = Column( INTEGER )
  fqdn            = Column( VARCHAR(255) )

  slots   = relationship("Slots")
  changes = relationship("PortStateLog")
  ports   = relationship("Ports", primaryjoin="and_(Slots.device==Devices.did,Ports.slot==Slots.sid)")


class Slots(Base):
  __tablename__ = 'slots'
  __table_args__ = {
    'mysql_engine' : 'MyISAM',
    'mysql_charset': 'latin1'
  }

  sid         = Column( INTEGER, primary_key=True )
  device      = Column( INTEGER, ForeignKey('devices.did'), default=None )
  slot        = Column( VARCHAR(10) )
  module      = Column( INTEGER )
  slot_status = Column( INTEGER )
  card_status = Column( INTEGER )

  ports = relationship("Ports", primaryjoin="Ports.slot==Slots.sid")


class Ports(Base):
  __tablename__ = 'ports'
  __table_args__ = {
    'mysql_engine' : 'MyISAM',
    'mysql_charset': 'latin1'
  }

  pid         = Column( INTEGER, primary_key=True )
  slot        = Column( INTEGER, ForeignKey('slots.sid'), default=None )
  port        = Column( INTEGER )
  name        = Column( VARCHAR(200) )
  status      = Column( INTEGER )
  description = Column( VARCHAR(200) )
  op_status   = Column( VARCHAR(40) )
  substatus   = Column( INTEGER(4) )
  type        = Column( INTEGER )
  clean       = Column( TINYINT(4) )
  speed       = Column( INTEGER(10) )
  duplex      = Column( CHAR(1) )
  sfp         = Column( INTEGER )

以上是我目前所掌握的。。我只希望下面最后一行返回所有端口:

^{pr2}$

非常感谢任何帮助。在


Tags: 端口basestatusmysqlcolumnintegerportsclass
1条回答
网友
1楼 · 发布于 2024-04-20 10:40:31

我认为在设备类定义的最后一行中端口关系定义有问题。我必须删除它才能在本地使用你的模式。另外,您没有包含任何__init__函数,所以我修改了这些函数来创建一些示例数据。在

我相信您已经知道这一点,但是如果您愿意遍历设备的插槽,您可以轻松地处理设备的端口列表:

d1 = session.query(Devices).filter_by(hostname='host1').first()
for slot in d1.slots:
    for port in slot.ports:
        #do something with each Ports object

跳过中间槽级别的一个简单方法是在Devices类中添加一点语法糖:

^{pr2}$

如果您真的想在与插槽相同的设备级别上组合端口,则需要构造一个AssociationProxy(而不是Association)来映射端口集合。但是,由于您没有维护多对多的关系,所以AssociationProxy看起来有点过头了,需要做一些工作来让它返回端口对象列表而不是pid列表。在

相关问题 更多 >