Определение отношения на таблице ассоциации с фильтрацией - PullRequest
0 голосов
/ 09 мая 2019

Этот пример развивается в таблице связей Родитель / Ребенок в документах SQLAlchemy (https://docs.sqlalchemy.org/en/13/orm/basic_relationships.html#association-object)

Как определить атрибут «сын» или «дочь» в родительском классе, чтобы отфильтровать таблицу сопоставления для соответствующей таблицы дочерних типов?

Я понимаю, как работают отношения "дети", но я бы хотел добавить в отношения дополнительные условия. Я подозреваю, что это связано с использованием 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 Ответ

1 голос
/ 10 мая 2019

Фильтрация таблицы ассоциации во вторичном объекте для включения только строк интересующего вас типа для каждого отношения, кажется, работает:

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
    )

... но добавление объектов через эти отношения не будетработают, поскольку они не знают, как создать объект ассоциации с child_type, следовательно, viewonly.Кроме того, я изменил Association.child_type на child_type_id = Column(Integer, ForeignKey('child_type.id')), поэтому в этом примере все по-другому.

Элемент Child / ChildType выделяется как возможное применение наследования 'класса отображения.Шаблон иерархии, если вы не привязаны к этой схеме, это может быть что-то для изучения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...