0

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

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

根据我的经验,这显示为:

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

我正在尝试在我的 Devices 类中建立一个关系,该关系将为我提供所有关联的 Ports 对象(无论插槽如何)。我想不通。关联表看起来很接近,但我无法从周围的例子中辨别出如何做我想做的事。

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 )

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

d = session.query(Devices).first()

d.ports

非常感谢任何帮助。

4

1 回答 1

0

我认为您的设备类定义的最后一行中的端口关系定义存在问题。我必须将其删除才能在本地使用您的架构。此外,您还没有包含任何__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

跳过中间 Slots 级别的一种简单方法是在您的 Devices 类中添加一些语法糖:

def ports(self):
    my_ports = []
    for slot in self.slots:
        my_ports.extend(slot.ports)
    return(my_ports)

如果您真的想在设备的同一级别上组合端口作为插槽,您将需要构造一个AssociationProxy(而不是Association)来映射端口集合。但是,由于您没有维护多对多关系,AssociationProxy 似乎有点矫枉过正,需要一些工作才能使其返回 Ports 对象列表而不是 pid 列表。

于 2012-07-14T00:40:04.523 回答