【问题标题】:multiple/split class associations in sqlalchemysqlalchemy 中的多个/拆分类关联
【发布时间】:2016-02-25 10:59:41
【问题描述】:

我定义了以下对象和关系。这实际上是一个非常简单的案例,我提供所有这些字段只是为了说明为什么我认为吸入麻醉和注射麻醉应该由两个不同的类别来定义。

class InhalationAnesthesia(Base):
    __tablename__ = "inhalation_anesthesias"
    id = Column(Integer, primary_key=True)
    anesthetic = Column(String)
    concentration = Column(Float)
    concentration_unit = Column(String)
    duration = Column(Float)
    duration_unit = Column(String)


class TwoStepInjectionAnesthesia(Base):
    __tablename__ = "twostep_injection_anesthesias"
    id = Column(Integer, primary_key=True)
    anesthetic = Column(String)
    solution_concentration = Column(Float)
    solution_concentration_unit = Column(String)
    primary_dose = Column(Float)
    primary_rate = Column(Float)
    primary_rate_unit = Column(String)
    secondary_rate = Column(Float)
    secondary_rate_unit = Column(String)

class Operation(Base):
    __tablename__ = "operations"
    id = Column(Integer, primary_key=True)
    anesthesia_id = Column(Integer, ForeignKey('inhalation_anesthesias.id'))
    anesthesia = relationship("InhalationAnesthesia", backref="used_in_operations")

不过,我想以这样一种方式定义 Operation 类的麻醉属性,使任何 Operation 对象都可以指向 TwoStepInjectionAnesthesia 对象或 InhalationAnesthesia 对象。

我该怎么做?

【问题讨论】:

    标签: python orm sqlalchemy object-relational-model


    【解决方案1】:

    我建议你使用继承。在 SqlAlchemy 文档 herehere 中有非常非常好的解释

    我的建议是创建一个Anesthesia 类并让InhalationAnesthesiaTwoStepInjectionAnesthesia 都从它继承。由您决定使用哪种类型的表继承:

    • 单表继承
    • 具体表继承
    • 连接表继承

    最常见的继承形式是单表和连接表, 而具体的继承提出了更多的配置挑战。


    对于您的情况,我假设 加入表继承 是选举:

    class Anesthesia(Base)
        __tablename__ = 'anesthesias'
        id = Column(Integer, primary_key=True)
        anesthetic = Column(String)
        # ...
        # every common field goes here
        # ...
        discriminator = Column('type', String(50))
        __mapper_args__ = {'polymorphic_on': discriminator}
    

    discriminator字段的用途:

    ... 是充当鉴别器,并存储 一个值,指示行内表示的对象的类型。 该列可以是任何数据类型,但字符串和整数是 最常见。

    __mapper_args__polymorphic_on 键定义哪个字段用作鉴别器。 在子类(如下)中,polymorphic_identity 键定义了将存储在类实例的多态鉴别器列中的值。

    class InhalationAnesthesia(Anesthesia):
        __tablename__ = 'inhalation_anesthesias'
        __mapper_args__ = {'polymorphic_identity': 'inhalation'}
        id = Column(Integer, ForeignKey('anesthesias.id'), primary_key=True)
        # ...
        # specific fields definition
        # ...
    
    
    class TwoStepInjectionAnesthesia(Anesthesia):
        __tablename__ = 'twostep_injection_anesthesias'
        __mapper_args__ = {'polymorphic_identity': 'twostep_injection'}
        id = Column(Integer, ForeignKey('anesthesias.id'), primary_key=True)
        # ...
        # specific fields definition
        # ...
    

    最后Operation 类可以引用父表Anesthesia 具有典型关系:

    class Operation(Base):
        __tablename__ = 'operations'
        id = Column(Integer, primary_key=True)
        anesthesia_id = Column(Integer, ForeignKey('anesthesias.id'))
        anesthesia = relationship('Anesthesia', backref='used_in_operations')
    

    希望这就是你要找的。​​p>

    【讨论】:

    • 所以使用这个设置我应该能够引用Operation.anesthesia 下的InhalationAnesthesiaTwoStepInjectionAnesthesia 对象?使用Operation.anesthesia = [TwoStepInjectionAnesthesia(..), InhalationAnesthesia(..), Inhalationanesthesia(..)] 会搞砸什么吗?
    • @TheChymera 是的,是的。在提供的示例中,Operation 实例将仅引用一个 Anesthesia 对象。如果你需要它是一个列表,你应该稍微改变一下代码。
    • 还有一件事,使用上述设置有什么好处(除了在 python 端组织得更好)?生成的实际 sql 表是否仅包含具有某些鉴别符的行的某些列类型? (从而节省磁盘空间?)
    猜你喜欢
    • 1970-01-01
    • 2021-09-23
    • 1970-01-01
    • 2019-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多