2015-11-23 62 views
5

我定义了以下对象和关系。这实际上是一个很简单的例子,我提供的所有这些领域仅仅是为了说明我为什么认为吸入麻醉和注射麻醉应该由两个不同的类别定义。sqlalchemy中的多个/拆分类关联

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对象可以指向一个TwoStepInjectionAnesthesia对象或InhalationAnesthesia对象Operation类的麻醉剂属性。

我该怎么做?

回答

6

我建议你使用继承。它在SQLAlchemy的文档非常,非常好解释herehere

我的建议是建立一个Anesthesia类,然后从它使双方InhalationAnesthesiaTwoStepInjectionAnesthesia继承。这是你的电话,以决定表继承使用哪种类型:

  • 单表继承
  • 混凝土表继承
  • 加入表继承

继承的最常见的形式是单加入表, 而具体继承呈现更多配置挑战。


对于你的情况,我asuming 加入表继承是选:

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') 

希望这是你在找什么。

+0

所以使用这个设置,我应该能够在Operation.anesthesia下引用'吸气麻醉'和'TwoStepInjectionAnesthesia'对象?会使用'Operation.anesthesia = [TwoStepInjectionAnesthesia(..),InhalationAnesthesia(..),Inhalationanesthesia(..)]'乱七八糟吗? – TheChymera

+0

@ TheChymera是和是。在提供的示例中,“Operation”实例将仅引用一个“麻醉”对象。如果你需要它是一个列表,你应该稍微改变一下代码。 –

+0

还有一件事,使用上述设置的好处是什么(除了在python末尾稍微更好地组织)?将生成的实际SQL表包含某些列类型仅适用于具有某些discrminators的行? (从而节省磁盘空间?) – TheChymera