sqlalchemy中的多个/拆分类关联

The*_*era 5 python orm sqlalchemy object-relational-model

我定义了以下对象和关系.这实际上是一个非常简单的案例,我提供所有这些领域只是为了说明为什么我认为吸入和注射麻醉应该由两个不同的类别来定义.

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")
Run Code Online (Sandbox Code Playgroud)

但是,我想Operation以这样的方式定义类的麻醉属性,即任何Operation对象都可以指向TwoStepInjectionAnesthesia对象或InhalationAnesthesia对象.

我怎样才能做到这一点?

Rob*_*nso 6

我建议你使用继承.在这里这里的 SqlAlchemy文档中非常非常好地解释了它

我的建议是创建一个Anesthesia类并同时创建它InhalationAnesthesiaTwoStepInjectionAnesthesia继承它.您可以决定使用哪种类型的表继承:

  • 单表继承
  • 具体表继承
  • 连接表继承

最常见的继承形式是单一和连接表,而具体的继承提出了更多的配置挑战.


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

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}
Run Code Online (Sandbox Code Playgroud)

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
    # ...
Run Code Online (Sandbox Code Playgroud)

最后,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')
Run Code Online (Sandbox Code Playgroud)

希望这是你正在寻找的.