2012-07-11 78 views
0

我有三个表:设备,插槽,端口。三个表之间的SQLAlchemy关系

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

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

  1. 设备(一对多)插槽
  2. 槽孔(一至毫安NY)端口

我想在我的设备类中设置一个关系,它会给我所有关联的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 

任何帮助是极大的赞赏。

回答

0

我认为在Devices类定义的最后一行中的端口关系定义存在问题。我必须删除它才能在本地处理您的模式。此外,您还没有包含任何__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 

一个简单的方法来跳过中间槽水平将是一个小语法糖添加到您的设备类:

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

如果你真的想撰写的设备作为相同的时隙级端口,你将需要构建一个AssociationProxy(不是Association )来映射端口的集合。但是,由于您没有保持多对多的关系,因此AssociationProxy看起来像是矫枉过正,需要一些工作才能使其返回Ports对象列表,而不是pid列表。

+0

我很抱歉,我没有回应。如果它解决了我的问题,我会审核并更新此评论/批准。我直到现在才注意到这一点! – Trenton 2013-03-01 21:10:52