0

デバイス、スロット、ポートの 3 つのテーブルがあります。

  1. デバイスには複数のスロットがあります
  2. スロットには複数のポートがありますが、単一のデバイスに属します
  3. ポートは単一のスロットに属します

私の経験では、これは次のように表示されます。

  1. デバイス (1 対多) スロット
  2. スロット (1 対多) ポート

関連するすべてのポート オブジェクト (スロットに関係なく) を提供するデバイス クラスで関係を設定しようとしています。私はそれを理解することはできません。アソシエーション テーブルはよく似ていますが、私がやりたいことを行う方法について、周りの例から見分けることができません。

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

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

その中間の Slots レベルをスキップする簡単な方法は、Devices クラスに構文糖衣を少し追加することです。

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

デバイスのスロットと同じレベルでポートを作成したい場合は、AssociationProxy (Association ではなく)を作成して、ポートのコレクションをマップする必要があります。ただし、多対多の関係を維持していないため、AssociationProxy はやり過ぎのように見え、pid のリストではなく Ports オブジェクトのリストを返すようにするには、多少の作業が必要になります。

于 2012-07-14T00:40:04.523 に答える