Python SQLAlchemy中与不同其他对象、自我和属性的多对多关系

Python SQLAlchemy中与不同其他对象、自我和属性的多对多关系,python,orm,sqlalchemy,Python,Orm,Sqlalchemy,我用SQLAlchemy声明了一个有点复杂的模型。我有一些基本对象,如(在这种情况下字段并不重要): 现在,我想声明这样一个对象的集合,使用简单的关系很容易,但不幸的是,我需要下面的类C: 名为members的单个字段,可指向任意数量的A和B对象 它还需要能够包含对其他C对象的引用 映射需要附加一个属性 我认为第三个要点很简单,如中所述。我不知道第一个是否可行,我也不知道第二个是否可行。我尝试了一个简单的关系('C'),但这导致SQLAlchemy抱怨了很多关于重复外键字段的问题。答案是使用

我用SQLAlchemy声明了一个有点复杂的模型。我有一些基本对象,如(在这种情况下字段并不重要):

现在,我想声明这样一个对象的集合,使用简单的
关系
很容易,但不幸的是,我需要下面的
类C

  • 名为
    members
    的单个字段,可指向任意数量的
    A
    B
    对象
  • 它还需要能够包含对其他
    C
    对象的引用
  • 映射需要附加一个属性

我认为第三个要点很简单,如中所述。我不知道第一个是否可行,我也不知道第二个是否可行。我尝试了一个简单的
关系('C')
,但这导致SQLAlchemy抱怨了很多关于重复外键字段的问题。

答案是使用连接表继承

首先,为类似的类添加一个公共父类,并使用名为type(或任何其他名称)的字段作为鉴别器

class E(Base):
    __tablename__ = 'es'
    id = COlumn(Integer, primary_key=True)
    type = Column(String)
…然后添加映射器参数:

    __mapper_args__ = {
        'polymorphic_identity': 'es',
        'polymorphic_on': type,
        'with_polymorphic': '*'
    }
让类似的类从中继承

class A(E):
    __tablename__ = 'as'
…并让他们使用共享主键/外键和正确的映射器参数:

    id = Column(Integer, ForeignKey('es.id'), primary_key=True)

    __mapper_args__ = {
        'polymorphic_identity': 'as'
    }
(同样适用于
B

然后可以定义与类
E
的关系

如果省略backref,则与包含关系本身的类的关系就可以工作

    id = Column(Integer, ForeignKey('es.id'), primary_key=True)

    __mapper_args__ = {
        'polymorphic_identity': 'as'
    }