Выражение гибридного свойства - выберите из подразделенияPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Выражение гибридного свойства - выберите из подразделения

Сообщение Anonymous »

Предположим, у меня есть следующая модель. У нас есть студенты, которые сдают экзамены по определенному предмету. Субъект может иметь несколько экзаменов, но рассматриваются только последние экзамены. Считается, что студент проходит, если он сдал последний экзамен всех своих предметов.

Код: Выделить всё

from sqlalchemy import select, func, ForeignKey, create_engine, Table, Column
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import Mapped, mapped_column, relationship, sessionmaker, DeclarativeBase, registry

reg = registry()

student_subjects = Table(
"student_subjects",
reg.metadata,
Column('student_idx', ForeignKey('student.idx'), primary_key=True),
Column('subject_idx', ForeignKey('subject.idx'), primary_key=True)
)

@reg.mapped_as_dataclass
class Student:
__tablename__ = "student"
idx: Mapped[int] = mapped_column(primary_key=True, init=False, autoincrement=True)
name: Mapped[str] = mapped_column()
exams: Mapped[list["Exam"]] = relationship(back_populates="student", init=False, default_factory=list)
subjects: Mapped[list["Subject"]] = relationship(back_populates="students", init=False, default_factory=list, secondary=student_subjects)

@hybrid_property
def latest_exams(self):
ret = []

for subject in self.subjects:
exams = [exam for exam in self.exams if exam.subject == subject]
exams.sort(key=lambda x: x.completed_at, reverse=True)

if len(exams) > 0:
ret.append(exams[0])

return ret

@reg.mapped_as_dataclass
class Subject:
__tablename__ = "subject"
idx: Mapped[int] = mapped_column(primary_key=True, init=False, autoincrement=True)
name: Mapped[str] = mapped_column()
exams: Mapped[list["Exam"]] = relationship(back_populates="subject", init=False)
students: Mapped[list["Student"]] = relationship(back_populates="subjects", init=False, secondary=student_subjects)

@reg.mapped_as_dataclass
class Exam:
__tablename__ = "Exam"

idx: Mapped[int] = mapped_column( primary_key=True, init=False, autoincrement=True)
passed: Mapped[bool] = mapped_column()

subject: Mapped["Subject"] = relationship(back_populates="exams")
subject_idx: Mapped[int] = mapped_column(ForeignKey("subject.idx"), init=False)

student: Mapped["Student"] = relationship(back_populates="exams")
student_idx: Mapped[int] = mapped_column(ForeignKey("student.idx"), init=False)

completed_at: Mapped[datetime] = mapped_column(default_factory=datetime.now)
< /code>
Я хочу написать гибридный атрибут, который позволяет мне запросить, прошел ли студент их тесты.stmt = select(Student).where(Student.passed)
< /code>
Я написал следующее выражение SQL. Внутренняя подразделение находит последние тесты всех предметов, которые проходит студент. Затем тесты проходят группы по студенческому, и не сбои, и подсчитываются неудачные тесты. Если есть ровно 0 неудачных тестов, студент помечен как пройден.SELECT
anon_1.student_idx,
count(CASE WHEN (anon_1.exam_passed IS 0) THEN 1 END) = 0 AS student_passed
FROM (
SELECT
student.idx AS student_idx,
"Exam".idx AS exam_idx,
max("Exam".completed_at) AS max_1,
"Exam".passed AS exam_passed
FROM student
JOIN "Exam" ON student.idx = "Exam".student_idx
GROUP BY "Exam".student_idx, "Exam".subject_idx
) AS anon_1
GROUP BY anon_1.student_idx
< /code>
Я могу написать запрос в Sqlalchemy, как SO, но я не знаю, как реализовать это в выражение гибридного свойства.latest_exams = (
select(
Student,
Student.idx.label("student_idx"),
Exam.idx.label("exam_idx"),
func.max(Exam.completed_at),
)
.join(Student.exams)
.group_by(Exam.student_idx, Exam.subject_idx)
)

subq = latest_exams.subquery()
stmt = (
select(label("student_passed", func.count(case((Exam.passed == 0, 1)))))
.select_from(subq)
.join(Exam, Exam.idx == subq.c.exam_idx)
.group_by(subq.c.student_idx)
)
Как перевести этот запрос в гибридное свойство?

Подробнее здесь: https://stackoverflow.com/questions/794 ... m-subquery
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»