如何在此查询中添加条件?

时间:2019-04-27 06:59:05

标签: python sqlalchemy flask-sqlalchemy

我正在使用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()

1 个答案:

答案 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()