2015-11-23 5 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 класса таким образом, что любой Operation объекта может указывать либо на TwoStepInjectionAnesthesia объект или InhalationAnesthesia объекта.

Как я могу это сделать?

ответ

6

Предлагаю вам использовать наследование. Это очень, очень хорошо объяснено в SQLAlchemy документации here и here

Моя рекомендация состоит в том, чтобы создать Anesthesia класс и сделать как InhalationAnesthesia и TwoStepInjectionAnesthesia наследуют от него. Это ваш вызов, чтобы решить, какой тип использования таблицы наследования:

  • одна таблицы наследование
  • бетона таблицы наследование
  • присоединился к таблице наследование

Наиболее распространенные формы наследования одного и соединенный стол, , в то время как конкретное наследование представляет больше конфигурационных проблем.


В вашем случае я 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__ «s 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

Так что, используя эту настройку, я должен иметь возможность ссылаться как на объекты «Ингаляционная анестезия», так и на объекты «TwoStepInjectionAnesthesia» в разделе «Operation.anesthesia»? Использует 'Operation.anesthesia = [TwoStepInjectionAnesthesia (..), InhalationAnesthesia (..), Inhalationanesthesia (..)]' mess что-нибудь? – TheChymera

+0

@ TheChymera Да и да. В приведенном примере экземпляр 'Operation' будет ссылаться только на один объект Anesthesia. Если вам нужно, чтобы это был список, вы должны немного изменить код. –

+0

Еще одна вещь: в чем преимущество использования вышеприведенной настройки (кроме того, что она немного лучше организована на конце python)? будет ли созданная фактическая таблица sql содержать определенные типы столбцов только для строк с определенными дискриматорами? (тем самым экономя дисковое пространство?) – TheChymera