我正在使用flask_sqlalchemy。
我有2个班的10名学生,需要收费。
通过school_class_id
时,我只需要返回特定班级的学生,其他所有学生即可。
第一个查询可以很好地列出所有学生。
在第二个代码中,添加了school_class_id
并按预期列出了特定班级的学生。
但是当我在school_class_id
条件下添加一个if
过滤器时,它只会返回一个学生。
此代码可以很好地获取所有学生:
result = db.session.query(
Student, SchoolClass, Guardian,
func.sum(StudentFee.net_payable).label('total_payable'),
).filter(
and_(SchoolClass.school_id == user['school_id'],
SchoolClass.id == Student.school_class_id),
SchoolClass.status == GenEnum.ACTIVE.value).join(
StudentGuardian, StudentGuardian.student_id == Student.id).filter(
Guardian.id == StudentGuardian.guardian_id
).outerjoin(StudentFee,
StudentFee.student_id == Student.id
).filter(StudentFee.status == NewEnum.ACTIVE.value).group_by(Student.id)
result.all()
此代码在传递school_class_id
时有效:
result = db.session.query(
Student, SchoolClass, Guardian,
func.sum(StudentFee.net_payable).label('total_payable'),
).filter(
and_(SchoolClass.school_id == user['school_id'],
# SchoolClass.id == body.get('school_class_id'),
SchoolClass.id == Student.school_class_id),
SchoolClass.status == GenEnum.ACTIVE.value).join(
StudentGuardian, StudentGuardian.student_id == Student.id).filter(
Guardian.id == StudentGuardian.guardian_id
).outerjoin(StudentFee,
StudentFee.student_id == Student.id
).filter(StudentFee.status == NewEnum.ACTIVE.value).group_by(Student.id)
result.all()
但是后来添加过滤器的此代码存在一些问题,因为它仅返回一名学生:
result = db.session.query(
Student, SchoolClass, Guardian,
func.sum(StudentFee.net_payable).label('total_payable'),
)
if body.get('school_class_id'):
result.filter(SchoolClass.id == body.get('school_class_id'))
result.filter(
and_(SchoolClass.school_id == user['school_id'],
SchoolClass.id == Student.school_class_id),
SchoolClass.status == GenEnum.ACTIVE.value).join(
StudentGuardian, StudentGuardian.student_id == Student.id).filter(
Guardian.id == StudentGuardian.guardian_id
).outerjoin(StudentFee,
StudentFee.student_id == Student.id
).filter(StudentFee.status == NewEnum.ACTIVE.value).group_by(Student.id)
result.all()
答案 0 :(得分:1)
SQLAlchemy Query
对象是可生成的。换句话说,诸如Query.filter()
之类的方法将产生一个新对象,而不是对现有对象进行突变。在尝试添加条件过滤时,您将产生并丢弃2个新查询。结果仅得到1行的原因是,最终运行的实际查询具有不带显式GROUP BY
子句的聚合,因此整个集合被视为单个组。修复很简单,只需在添加过滤器等时重新分配查询即可:
result = db.session.query(...)
if body.get('school_class_id'):
result = result.filter(...)
result = result.filter(...).join(...).outerjoin(...).filter(...).group_by(...)
result.all()