2012-07-11 142 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