Объединение нескольких таблиц SQLAlchemy в поле связи в классе модели

#python #sqlalchemy

#python #sqlalchemy

Вопрос:

Давайте предположим ситуацию, в которой есть 3 таблицы или, можно сказать, классы моделей:

  • Пользователь
  • Школа
  • Тема

В таком отношении: User ManyToMany School множество Subject . Эти отношения «многие ко многим» определены в таблицах ассоциаций следующим образом:

 school_user = db.Table('school_user ',
                     db.Column('user_id', db.Integer, db.ForeignKey('users.id')),
                     db.Column(school_id', db.Integer, db.ForeignKey('schools.id')))


subject_school = db.Table('subject_school ',
                           db.Column('school_id', db.Integer, db.ForeignKey('schools.id')),
                           db.Column('subject_id', db.Integer, db.ForeignKey('subjects.id')))

class User(db.Model):
    schools= db.relationship('School', secondary=school_user , backref=db.backref('users', lazy='dynamic'))

class Subject(db.Model):
    schools= db.relationship('School',
                              secondary=subject_school,
                              backref=db.backref('subjects',
                                                 lazy='dynamic'))
  

Я хотел бы запросить все, Subjects что принадлежит Schools тому User , к которому относится.

Я могу легко достичь этого с помощью:

 class User:
    @property
    def subjects(self):
        return (Subject
                .query
                .join(School, Subject.schools)
                .join(User, School.users)
                .filter(User.id == self.id)
                .all())
  

Мой вопрос: возможно ли это с помощью поля отношения SQLAlchemy с использованием primaryjoin и secondaryjoin ? Что-то вроде (не работает, для демонстрационных целей):

 class User:
    subjects = db.relationship('Subject', 
                               secondary=subject_school, 
                               secondaryjoin='School.id==subject_school.c.school_id', 
                               primaryjoin='Subject.id==subject_school.c.subject_id')
  

Очевидно, что пользовательское объединение отсутствует в примере выше, потому что я не знаю, как его правильно применить.