2015-11-23 5 views
5

以下のオブジェクトとリレーションが定義されています。これは実際には非常に単純なケースです。私は吸入と注射麻酔が2つの異なるクラスによって定義されるべきだと考える理由を示すために、これらのフィールドをすべて提供しています。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

継承を使用することをお勧めします。非常に、非常によくherehere

私の推薦はAnesthesiaクラスを作成し、それから、両方InhalationAnesthesiaTwoStepInjectionAnesthesia継承を作ることですSQLAlchemyのドキュメントで説明しています。これは、テーブル継承の使用のタイプを決定するためにあなたの呼び出しです:

  • 単一テーブル継承
  • 具象テーブル継承
  • 結合テーブル継承

継承の最も一般的な形態は、単一であり、 という具合です。具体的な継承はより多くの構成上の課題をもたらします。あなたのケースでは


私ははテーブル継承に入社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 keyは、クラスのインスタンスの多態性識別器列に格納される値を定義します。

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'の下で' InhalationAnesthesia'と 'TwoStepInjectionAnesthesia'オブジェクトの両方を参照できるはずですか? 'Operation.anesthesia = [TwoStepInjectionAnesthesia(..)、InhalationAnesthesia(..)、Inhalationanesthesia(..)]を使用しますか? – TheChymera

+0

@ TheChymeraはいとはい。提供された例では、「動作」インスタンスは1つの「麻酔」オブジェクトのみを参照する。それをリストにする必要がある場合は、コードを少し変更する必要があります。 –

+0

さらにもう1つ、上記の設定を使用する利点は何ですか?生成される実際のSQLテーブルには、特定のディスクリミネータを持つ行の特定の列タイプのみが含まれますか? (これによりディスク容量を節約できますか?) – TheChymera