【问题标题】:Querying for a particular subclass(child) in an inheritance will render the base class(parent) attributes in addition to the subclass attributes在继承中查询特定的子类(子类)将呈现除子类属性之外的基类(父类)属性
【发布时间】:2019-02-18 10:39:48
【问题描述】:

我是 sqlalchemy-ORM 的新手,我不知道要在我的代码中添加什么以使子表看到父表的属性 + 它自己的属性。

我正在使用 sqlalchemy-ORM 创建一个数据库。我在“设备”表(基类)、“集线器”和“控制器”(子类)之间进行了连接表继承。默认情况下,基类会看到它自己和子类的属性,但如果我想反其道而行之怎么办。我的问题是我的代码中的子类只看到它自己的属性,我希望它同时看到父类和它自己的属性。

class Device(Base):
    __tablename__ = "device"
    id = Column('id' , Integer , primary_key=True)
    name = Column('name' , String)
    status = Column('status', Boolean)
    room_id = Column(Integer , ForeignKey('room.id'))
    type = Column('type' , String)

    __mapper_args__ = {'polymorphic_identity':'device', 'polymorphic_on': type
        }

class Hub(Device):
    __tablename__ = "hub"
    id = Column('id' ,Integer , ForeignKey('device.id'), primary_key=True)      
    __mapper_args__ = {'polymorphic_identity':'hub'
        }

class Controller(Device):
    __tablename__ = "controller"
    id = Column('id' , Integer , ForeignKey('device.id'), primary_key=True)     
    __mapper_args__ = {'polymorphic_identity':'controller'
        }

【问题讨论】:

  • 明确一点,控制器和集线器是特定类型的设备,还是控制器和集线器连接不同的设备?
  • 它们是设备类型。
  • 好的。在下面提供一个可能的解决方案。

标签: python orm sqlalchemy


【解决方案1】:

您似乎试图做的是将大部分信息存储在您的设备对象上,然后通过将其链接到名为 Hub 和 Controller 的单独表中的记录来区分它。例如,如果您有 2 个控制器和一个集线器:

===============================================
Table: "device"
id    name        status    room_id    type  
===============================================
1    Hub A         True          1     Hub  
2    Troller A     True          1     Troll 
3    Troller B     False         8     Troll 
===============================================

============
Table: "hub"
id  
============
1
============

===================
Table: "controller"
id 
===================
2
3
===================

虽然这样的事情在其他情况下可能有意义,但它并没有利用您正在使用的关系数据库。相反,我建议您的所有设备只使用一个表,然后将它们链接到第二个设备类型表:

class Device(Base):
    __tablename__ = 'device'
    id = Column(Integer, primary_key=True)
    name = Column(String)
    status = Column(Boolean)
    room_id = Column(Integer, ForeignKey('room.id')
    type_id = Column(Integer, ForeignKey('device_type.id')
    type = relationship('DeviceType', backref='devices')

class DeviceType(Base):
    __tablename__ = 'device_type'
    id = Column(Integer, primary_key=True)
    name = Column(String)

别忘了from sqlalchemy.orm import relationship。这样,您可以选择一种类型,然后使用关系来获取该类型的所有设备。您还可以在将来添加新类型的设备,而无需添加全新的表格。

在这种情况下,上面的相同表格将显示为:

===============================================
Table: "device"
id    name        status    room_id    type_id  
===============================================
1    Hub A        True           1           1 
2    Troller A    True           1           2 
3    Troller B    False          8           3
===============================================

====================
Table: "device_type"
id    name
====================
1     Hub
2     Controller
====================

如果您想返回所有控制器的列表,只需查询控制器 device_type 并使用关系/backref 并获取所有关联设备:

controller_type = session.query(DeviceType).get(2)
controllers = controller_type.devices

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-08
    • 1970-01-01
    • 2016-10-17
    • 1970-01-01
    • 1970-01-01
    • 2012-05-03
    • 1970-01-01
    • 2015-05-03
    相关资源
    最近更新 更多