通过过滤在关联表上定义关系

时间:2019-05-09 13:27:02

标签: python database sqlalchemy

此示例在SQLAlchemy文档(https://docs.sqlalchemy.org/en/13/orm/basic_relationships.html#association-object)的“父/子”关联表上开发

如何在Parent类上定义'son'或'daughter'属性,以将关联表过滤到适当的子类型表?

我了解“孩子”关系的工作原理,但我想在关系中添加额外的条件。我怀疑这涉及在关系的定义中使用secondary,但这是我对SQLAlchemy中关系的理解的边缘。

    from sqlalchemy import Table, Column, Integer, ForeignKey, String
    from sqlalchemy.orm import relationship
    from sqlalchemy.ext.declarative import declarative_base

    Base = declarative_base()

    class Association(Base):
        __tablename__ = 'association'
        left_id = Column(Integer, ForeignKey('left.id'), primary_key=True)
        right_id = Column(Integer, ForeignKey('right.id'), primary_key=True)
        child = relationship("Child", back_populates="parents")
        parent = relationship("Parent", back_populates="children")
        child_type = Column(Integer, ForeignKey('child_type'))

    class Parent(Base):
        __tablename__ = 'left'
        id = Column(Integer, primary_key=True)
        children = relationship("Association", back_populates="parent")
        # I would also like to define 'sons' and 'daughters' here

    class Child(Base):
        __tablename__ = 'right'
        id = Column(Integer, primary_key=True)
        parents = relationship("Association", back_populates="child")

    class ChildType(Base):
        __tablename__ = 'child_type'
        id = Column(Integer, primary_key=True)
        name = Column(String(50))

    son_type = ChildType(name='son')
    daughter_type = ChildType(name='daughter')

    dad = Parent()
    son = Child()

    dad_son = Association(child_type=son_type)
    dad_son.child = son
    dad.children.append(dad_son)

    daughter = Child()
    dad_daughter = Association(child_type=daughter_type)
    dad_daughter.child = daughter
    dad.children.append(dad_daughter)

1 个答案:

答案 0 :(得分:0)

过滤辅助表中的关联表以仅包含您对每种关系都感兴趣的类型的行似乎可行:

translatesAutoresizing...

...但是通过这些关系添加对象将不起作用,因为它们不知道如何使用child_type来构造关联对象,因此class Parent(Base): __tablename__ = 'left' id = Column(Integer, primary_key=True) children = relationship("Association", back_populates="parent") # I would also like to define 'sons' and 'daughters' here sons = relationship( 'Child', secondary="join(Association, ChildType, " "and_(Association.child_type_id==ChildType.id, " "ChildType.name=='son'))", viewonly=True ) daughters = relationship( 'Child', secondary="join(Association, ChildType, " "and_(Association.child_type_id==ChildType.id, " "ChildType.name=='daughter'))", viewonly=True ) 也是如此。另外,我将viewonly更改为Association.child_type,这就是示例中与众不同的原因。

child_type_id = Column(Integer, ForeignKey('child_type.id')) / Child'Mapping Class Inheritance Hierarchies'模式的一种可能的应用,如果您不被该模式所限制,那可能是值得探索的东西。