In sqlalchemy, how to you test for unmatched tables when using an outerjoin on a many-to-many relationship.
I'm working with 5 tables/objects.
- Program: Art class, spanish class, etc
- Session: Child of Program, each program has several sessions, session stores date/time for each class
- Student: Students can enroll in Programs
- Enrollment: Associates students with Programs
- Attendance: Associates students with Sessions. Created lazily (not until needed)
In the below example I'm trying to find student absences. I perform an outerjoin on the Attendance table because the Attendance object doesn't always exist. I want to return rows where Attendance.absent == True
or rows where Attendance
is not matched (ie not yet created).
class Session(BaseModel):
id = db.Column(db.Integer, primary_key=True)
# list of Attendance objects for students that attended this session
attendance = db.relationship(Attendance, backref="session")
@classmethod
def get_absences(cls, student):
# I'm trying to return a list of sessions where this student was absent
# The query joins the Program table so it can join
# the enrollment table, so it can filter for enrollments
# for this student and then return sessions where
# the Attendance object has not been created or Attendance.absent == True
return (
cls.query
.join(Program)
.join(Enrollment)
.filter(Enrollment.student_id == student.id)
.outerjoin(Attendance)
# Attendance == None is not correct
.filter(or_(Attendance == None, Attendance.absent == True))
)
class Attendance(BaseModel):
id = db.Column(db.Integer, primary_key=True)
session_id = db.Column(db.Integer, db.ForeignKey('session.id') )
student_id = db.Column(db.Integer, db.ForeignKey('student.id'))
So Session.get_absences()
obviously doesn't work because Attendance == None
isn't overloaded and doesn't generate sql. How do I return sessions where the Attendance
object hasn't been created for a given Student
/ Session
pair?
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…