2015-11-23 70 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