2015-11-23 7 views
5

Ich habe die folgenden Objekte und Beziehungen definiert. Das ist eigentlich ein ganz einfacher Fall, und ich biete all diese Felder an, um zu zeigen, warum ich glaube, dass Inhalations- und Injektionsnarkose von zwei verschiedenen Klassen definiert werden sollte.multiple/split Klassenassoziationen in 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") 

I würde jedoch wie das Anästhetikum Attribut der Klasse Operation so zu definieren, dass jedes Operation Objekt entweder ein TwoStepInjectionAnesthesia Objekt zeigen kann oder ein InhalationAnesthesia Objekt.

Wie kann ich das tun?

Antwort

6

Ich empfehle Ihnen, Vererbung zu verwenden. Es ist sehr, sehr gut in sqlalchemy docs erklärt here und here

Meine Empfehlung ist, eine Anesthesia Klasse zu erstellen und sowohl InhalationAnesthesia und TwoStepInjectionAnesthesia erbt von ihm. Es ist Ihre Entscheidung, die Erbschaft Verwendung Art der Tabelle, um zu entscheiden: Vererbung

  • einzelne Tabelle Vererbung
  • Betontisch Erbe
  • verknüpfte Tabelle

Die häufigsten Formen der Vererbung sind Einzel- und beigefügte Tabelle, , während konkrete Vererbung mehr Konfigurationsherausforderungen darstellt.


Für Ihren Fall ich asuming Tabelle Erbschaft verbunden ist die Wahl:

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} 

Der Zweck discriminator Feld:

... ist zu handeln als der Diskriminator und speichert einen Wert, der den Typ des in der Reihe dargestellten Objekts angibt. Die Spalte kann einen beliebigen Datentyp haben, obwohl String und Integer die am häufigsten verwendeten Werte sind.

__mapper_args__ ‚s polymorphic_on Schlüssel definieren, welches Feld die Verwendung als Diskriminator. In untergeordneten Klassen, polymorphe_identität Schlüssel definieren den Wert, der in der polymorphen Diskriminatorspalte für Instanzen der Klasse gespeichert wird.

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

Hoffnung das ist, was Sie suchen:

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 
    # ... 

Schließlich wird die Operation Klasse die übergeordnete Tabelle Anesthesia mit einer typischen Beziehung verweisen kann.

+0

Mit diesem Setup sollte ich in der Lage sein, sowohl "InhalationAnästhesie" - als auch "TwoStepInjectionAnästhesie" -Objekte unter "Operation.anästhesie" zu referenzieren. Würde "Operation.anesthesia = [TwoStepInjektionAnästhesie (..), Inhalationsanästhesie (..), Inhalationsanästhesie (..)] etwas durcheinander bringen? – TheChymera

+0

@TheChymera Ja und Ja. In diesem Beispiel bezieht sich eine "Operations" -Instanz nur auf ein "Anästhesie" -Objekt. Wenn Sie eine Liste benötigen, sollten Sie den Code ein wenig ändern. –

+0

Noch eine Sache, was ist der Vorteil der Verwendung der oben genannten Einrichtung (abgesehen von etwas besser organisiert auf der Python-Ende)? Wird die tatsächliche SQL-Tabelle, die generiert wird, bestimmte Spaltentypen nur für Zeilen mit bestimmten Trennzeichen enthalten? (dadurch Speicherplatz sparen?) – TheChymera