python - SQLAlchemy:如何获取与当前用户无关的所有项目?

python - SQLAlchemy: how to get all items that are not related to current user?

我的目的是获取学生未参加的所有CourseModel项。该学生被 id 接走并且是 StudentModel 的实例。两个 table 都通过 table attending 链接为多对多关系。

attending = db.Table('attending',
                     db.Column('student_id', db.Integer, db.ForeignKey('students.id')),
                     db.Column('course_id', db.Integer, db.ForeignKey('courses.id')))

class StudentModel(db.Model):
    __tablename__ = "students"
    id = db.Column(db.Integer, primary_key=True)
    first_name = db.Column(db.String())
    last_name = db.Column(db.String())
    courses = db.relationship('CourseModel', secondary=attending, backref=db.backref('students_on_course', lazy='dynamic'))

class CourseModel(db.Model):
    __tablename__ = "courses"
    id = db.Column(db.Integer, primary_key=True)
    course_name = db.Column(db.String(), unique=True)
    description = db.Column(db.Text())

例如,我们有下一个数据:

      CourseModel                     attending
    ----------------            ----------------------
    id   course_name            student_id   course_id
    ----------------            ----------------------
     1   Biology                    1            1
     2   Math                       1            3
     3   Philosophy
     4   Design

id == 1 学生的成绩应该是 [(2, "Math"), (4, "Design")]

对于没有展示我尝试过的所有解决方案,我深表歉意,因为其中有很多,none 其中的一些让我更接近我的目标。我的主要概念如下。

available_courses = (db.session
                     .query(CourseModel)
                     .join(attending)
                     .join(StudentModel)
                     .filter(StudentModel.id == student_id)
                     .where(StudentModel.courses is None)  # can't find working condition for this place
                     )

您可以使用子查询来收集已参加的课程,然后在过滤器中使用它来获取缺少的课程:

from sqlalchemy.sql import select, not_
attended_courses_subq = select(attending.c.course_id).filter(attending.c.student_id == 1)
available_courses = session.query(CourseModel).filter(not_(CourseModel.id.in_(attended_courses_subq))).all()

恭喜我,我做到了!这个效果不错!

attended_courses = (db.session.query(attending.c.course_id)
                    .join(StudentModel)
                    .filter(StudentModel.id == student_id)
                    .subquery())
available_courses = (db.session
                    .query(CourseModel)
                    .filter(CourseModel.id.notin_(attended_courses))
                    .all())