Как добавить условие if в этом запросе? - PullRequest
1 голос
/ 27 апреля 2019

Я использую flask_sqlalchemy.

У меня 10 учеников в 2 классах с оплатой.

Когда 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 Ответ

1 голос
/ 27 апреля 2019

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()
...