访问SQLalchemy中的相关记录数据

时间:2015-03-15 19:35:44

标签: python sqlalchemy

我正在创建包含其名称和IP地址的以太网交换机数据库。此外,我存储该交换机中的活动端口列表(暂时处于UP状态)。在交换机的情况下,我使用其IP地址作为主键。不幸的问题从端口列表开始。它们可以具有重复的名称和编号(因为每个交换机可以具有端口号1,也可以具有名为“上行链路”的端口)。

所以我的想法是使用“switch_ip:port_name”形式的端口ID,例如:“1.2.3.4:Gi0/1”或“4.5.6.7:20”,以防端口号只是数字而不是名称。< / p>

我想这样做,Session.merge()有效。所以我会看到它:

class Switch(Base):
    __tablename__ = 'switches'

    name = Column(String(128), nullable=False)
    ip = Column(String(15), primary_key=True, nullable=False)

    ports = relationship("Port", order_by="Port.id", backref="switch")

    def __repr__(self):
            return "<Switch(name='%s', ip='%s')>" % (self.name, self.ip)

class Port(Base):
    __tablename__ = 'ports'

    id = Column(String(160), primary_key=True)
    number = Column(Integer) 
    name = Column(String(32)) 
    description = Column(String(255))

    switch_ip = Column(String(15), ForeignKey('switches.ip'))
    macs = relationship("Mac", order_by="Mac.mac", backref="port")

    def __init__(self, id, name, description, number = None):
            self.name = name
            self.description = description
            self.number = number
            self.id = self.switch_ip + ":" + name

    def __repr__(self):
            return "<Port(switch='%s', name='%s', description='%s')>" % (self.switch_ip, self.name, self.description)

感谢我能做到这样的事情:

sw = Switch(name='some-switch',ip='1.2.3.4')
sw.ports = [ Port(name='Gi0/666', description='Uplink'), Port(name='Gi0/24', description='Apartament2') ]

不幸的是,在Port.__init__中,其属性switch_ip为空(None)。但是在Session.add()Session.merge()将其存储在数据库中后,它会使用1.2.3.4正确填充值。但为时已晚。那么如何在switch_ip中获得Port.__init__值?

1 个答案:

答案 0 :(得分:0)

这是一个解决方案,使用上下文敏感的列插入默认值(此处记录 - http://docs.sqlalchemy.org/en/latest/core/defaults.html)。首先,我们创建函数返回由IP和端口名称组成的专有名称:

def portid(context):
    return context.current_parameters['switch_ip'] + ':' + context.current_parameters['name']

然后更新对象定义:

class Port(Base):
    __tablename__ = 'ports'

    id = Column(String(160), primary_key=True, default=portid)
    number = Column(Integer) 
    name = Column(String(32)) 
    description = Column(String(255))

    switch_ip = Column(String(15), ForeignKey('switches.ip'))
    macs = relationship("Mac", order_by="Mac.mac", backref="port")

    def __repr__(self):
            return "<Port(switch='%s', name='%s', description='%s')>" % (self.switch_ip, self.name, self.description)

voila