4

我有一棵看起来像这样的树,通过多态继承反映出来:

      A
  /   |   \
  B   C   D

这很好用,比如:

class BaseModel(db.Model):     # Table A in diagram
    __tablename__ = "entities"

    id = db.Column(db.BigInteger, primary_key=True, nullable=False, server_default=func.nextval('guid_seq'))
    type_id = db.Column(db.SmallInteger, db.ForeignKey(EntityTypesModel.id))

    __mapper_args__ = {
        'polymorphic_identity':'entity',
        'polymorphic_on':type_id,
        'with_polymorphic':'*'
    }

class BrandModel(BaseModel):   # Table B, C, D in diagram
    __tablename__ = 'brands'

    id = db.Column(db.BigInteger, db.ForeignKey(StufffModel.id), primary_key=True, nullable=False)
    name = db.Column(db.String, nullable=False)

    __mapper_args__ = {
        'polymorphic_identity':ET_BRAND,
    }

问题是我需要反映更多类似这样的东西:

              A
          /   |   \
          B   C   D
                /   \
                E    F

其中 D 不仅是 A 的多态子代,而且是 E & F 的多态父代。

似乎我必须选择,D 可以是多态的孩子,也可以是父母——不能两者兼而有之。

我在这里有什么选择吗?

编辑:

为了解决这个问题,我最终把树弄平了,所以它看起来像:

      A
  /   |   \   \
 B    C    E   F

D 现在消失了,它提供的功能在孩子(E&F)中。我可能会将公共部分做成 mixin 之类的。

不幸的是,我不能在这个特定问题上花费更多时间。

4

1 回答 1

5

你绝对可以做到这一点。下面的代码使用declarative_base,但显示了有效的模型设置。Dclass 是使用类继承的父类和子类。但是,polymorphic_identity仅存储在顶层。确保您设置了所有正确的外键和类继承。

*注意:您的示例将 type_id 定义为数字,但值似乎是字符串。*

Base = declarative_base(cls=_BaseMixin)
Base.query = session.query_property()

class BaseModel(Base):
    __tablename__ = 'entities'
    id = Column(Integer, primary_key=True)
    #type_id = Column(Integer, nullable=False)
    type_id = Column(String, nullable=False)
    __mapper_args__ = {
        'polymorphic_identity': 'entity',
        'polymorphic_on':type_id,
        'with_polymorphic':'*'
    }

class ModelB(BaseModel):
    __tablename__ = 'modelB'
    __mapper_args__ = {'polymorphic_identity': 'modelB'}
    id = Column(Integer, ForeignKey('entities.id'), primary_key=True)
    name = Column(String, nullable=False)

class ModelC(BaseModel):
    __tablename__ = 'modelC'
    __mapper_args__ = {'polymorphic_identity': 'modelC'}
    id = Column(Integer, ForeignKey('entities.id'), primary_key=True)
    name = Column(String, nullable=False)

class ModelD(BaseModel):
    __tablename__ = 'modelD'
    __mapper_args__ = {'polymorphic_identity': 'modelD'}
    id = Column(Integer, ForeignKey('entities.id'), primary_key=True)
    name = Column(String, nullable=False)

class ModelE(ModelD):
    __tablename__ = 'modelE'
    __mapper_args__ = {'polymorphic_identity': 'modelE'}
    id = Column(Integer, ForeignKey('entities.id'), ForeignKey('modelD.id'), primary_key=True)
    name = Column(String, nullable=False)

class ModelF(ModelD):
    __tablename__ = 'modelF'
    __mapper_args__ = {'polymorphic_identity': 'modelF'}
    id = Column(Integer, ForeignKey('entities.id'), ForeignKey('modelD.id'), primary_key=True)
    name = Column(String, nullable=False)
于 2013-06-04T07:55:24.447 回答