Справка по сложному соединению SQL Alchemy - PullRequest
1 голос
/ 28 апреля 2011

Во-первых, обзор базы данных:

  • competitors - люди, которые соревнуются
  • competitions - вещи, на которых люди соревнуются
  • competition_registrations - Участники, зарегистрированные на конкретный конкурс
  • event - «событие» на соревновании.
  • events_couples - пара (2 участника), участвующая в соревновании.

Во-первых, EventCouple, класс Python, соответствующий events_couples, равен:

class EventCouple(Base):
    __tablename__ = 'events_couples'

    competition_id = Column(Integer, ForeignKey('competitions.id'), primary_key=True)
    event_id = Column(Integer, ForeignKey('events.id'), primary_key=True)

    leader_id = Column(Integer)
    follower_id = Column(Integer)

    __table_args__ = (
        ForeignKeyConstraint(['competition_id', 'leader_id'], ['competition_registrations.competition_id', 'competition_registrations.competitor_id']),
        ForeignKeyConstraint(['competition_id', 'follower_id'], ['competition_registrations.competition_id', 'competition_registrations.competitor_id']),
        {}
    )

У меня есть класс Python, CompetitorRegistration, который соответствует записи / строке в competition_registrations. Участник, который зарегистрирован, может участвовать в нескольких соревнованиях, но либо как «лидер», либо как «последователь». Я хотел бы добавить к CompetitorRegistration атрибут leading, то есть список EventCouple, где competition_id и leader_id совпадают. Это мой CompetitorRegistration класс, в комплекте с попыткой:

class CompetitorRegistration(Base):
    __tablename__ = 'competition_registrations'

    competition_id = Column(Integer, ForeignKey('competitions.id'), primary_key=True)
    competitor_id = Column(Integer, ForeignKey('competitors.id'), primary_key=True)
        email = Column(String(255))
    affiliation_id = Column(Integer, ForeignKey('affiliation.id'))
    is_student = Column(Boolean)
    registered_time = Column(DateTime)
    leader_number = Column(Integer)

    leading = relationship('EventCouple', primaryjoin=and_('CompetitorRegistration.competition_id == EventCouple.competition_id', 'CompetitorRegistration.competitor_id == EventCouple.leader_id'))
    following = relationship('EventCouple', primaryjoin='CompetitorRegistration.competition_id == EventCouple.competition_id and CompetitorRegistration.competitor_id == EventCouple.follower_id')

Однако я получаю:

ArgumentError: Could not determine relationship direction for primaryjoin
condition 'CompetitorRegistration.competition_id == EventCouple.competition_id
AND CompetitorRegistration.competitor_id == EventCouple.leader_id', on
relationship CompetitorRegistration.leading. Ensure that the referencing Column
objects have a ForeignKey present, or are otherwise part of a
ForeignKeyConstraint on their parent Table, or specify the foreign_keys parameter
to this relationship.

Спасибо за любую помощь, и дайте мне знать, если требуется дополнительная информация о схеме.

Кроме того, еще одна моя попытка видна в following - это не было ошибкой, но и не давало правильных результатов. (Он только присоединился к competition_id и полностью проигнорировал follower_id)

1 Ответ

0 голосов
/ 29 апреля 2011

Ваше leading условие смешивает выражение и строку в eval() ed. И условие following смешивает операторы Python и SQL: and в Python не то, что вы ожидали здесь. Ниже приведены исправленные примеры с использованием обоих вариантов:

leading = relationship('EventCouple', primaryjoin=(
    (competition_id==EventCouple.competition_id) & \
    (competitor_id==EventCouple.leader_id)))

leading = relationship('EventCouple', primaryjoin=and_(
    competition_id==EventCouple.competition_id,
    competitor_id==EventCouple.leader_id))

following = relationship('EventCouple', primaryjoin=\
    '(CompetitorRegistration.competition_id==EventCouple.competition_id) '\
    '& (CompetitorRegistration.competitor_id==EventCouple.follower_id)')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...