Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 165 additions & 0 deletions migrations/versions/beb11fd89531_lecturer_rating.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
"""lecturer-rating

Revision ID: beb11fd89531
Revises: fc7cb93684e0
Create Date: 2025-08-25 14:59:47.363354

"""

import sqlalchemy as sa
from alembic import op


# revision identifiers, used by Alembic.
revision = 'beb11fd89531'
down_revision = 'fc7cb93684e0'
branch_labels = None
depends_on = None


def upgrade():
op.add_column(
'lecturer',
sa.Column(
'mark_weighted',
sa.Float(),
server_default='0.0',
nullable=False,
comment='Взвешенная оценка преподавателя, посчитана в dwh',
),
)
op.add_column(
'lecturer',
sa.Column(
'mark_kindness_weighted',
sa.Float(),
server_default='0.0',
nullable=False,
comment='Взвешенная оценка доброты, посчитана в dwh',
),
)
op.add_column(
'lecturer',
sa.Column(
'mark_clarity_weighted',
sa.Float(),
server_default='0.0',
nullable=False,
comment='Взвешенная оценка понятности, посчитана в dwh',
),
)
op.add_column(
'lecturer',
sa.Column(
'mark_freebie_weighted',
sa.Float(),
server_default='0.0',
nullable=False,
comment='Взвешенная оценка халявности, посчитана в dwh',
),
)
op.add_column(
'lecturer',
sa.Column(
'rank', sa.Integer(), server_default='0', nullable=False, comment='Место в рейтинге, посчитана в dwh'
),
)
op.add_column(
'lecturer',
sa.Column(
'rank_update_ts',
sa.DateTime(),
server_default=sa.func.now(),
nullable=False,
comment='Время обновления записи',
),
)
op.alter_column(
'lecturer',
'id',
existing_type=sa.INTEGER(),
comment='Идентификатор преподавателя',
existing_nullable=False,
autoincrement=True,
existing_server_default=sa.text("nextval('lecturer_id_seq'::regclass)"),
)
op.alter_column(
'lecturer', 'first_name', existing_type=sa.VARCHAR(), comment='Имя препода', existing_nullable=False
)
op.alter_column(
'lecturer', 'last_name', existing_type=sa.VARCHAR(), comment='Фамилия препода', existing_nullable=False
)
op.alter_column(
'lecturer', 'middle_name', existing_type=sa.VARCHAR(), comment='Отчество препода', existing_nullable=False
)
op.alter_column(
'lecturer', 'avatar_link', existing_type=sa.VARCHAR(), comment='Ссылка на аву препода', existing_nullable=True
)
op.alter_column(
'lecturer',
'is_deleted',
existing_type=sa.BOOLEAN(),
comment='Идентификатор софт делита',
existing_nullable=False,
existing_server_default=sa.text('false'),
)


def downgrade():
op.alter_column(
'lecturer',
'is_deleted',
existing_type=sa.BOOLEAN(),
comment=None,
existing_comment='Идентификатор софт делита',
existing_nullable=False,
existing_server_default=sa.text('false'),
)
op.alter_column(
'lecturer',
'avatar_link',
existing_type=sa.VARCHAR(),
comment=None,
existing_comment='Ссылка на аву препода',
existing_nullable=True,
)
op.alter_column(
'lecturer',
'middle_name',
existing_type=sa.VARCHAR(),
comment=None,
existing_comment='Отчество препода',
existing_nullable=False,
)
op.alter_column(
'lecturer',
'last_name',
existing_type=sa.VARCHAR(),
comment=None,
existing_comment='Фамилия препода',
existing_nullable=False,
)
op.alter_column(
'lecturer',
'first_name',
existing_type=sa.VARCHAR(),
comment=None,
existing_comment='Имя препода',
existing_nullable=False,
)
op.alter_column(
'lecturer',
'id',
existing_type=sa.INTEGER(),
comment=None,
existing_comment='Идентификатор преподавателя',
existing_nullable=False,
autoincrement=True,
existing_server_default=sa.text("nextval('lecturer_id_seq'::regclass)"),
)
op.drop_column('lecturer', 'rank_update_ts')
op.drop_column('lecturer', 'rank')
op.drop_column('lecturer', 'mark_freebie_weighted')
op.drop_column('lecturer', 'mark_clarity_weighted')
op.drop_column('lecturer', 'mark_kindness_weighted')
op.drop_column('lecturer', 'mark_weighted')
71 changes: 45 additions & 26 deletions rating_api/models/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
)
from sqlalchemy import Enum as DbEnum
from sqlalchemy import (
Float,
ForeignKey,
Integer,
String,
Expand Down Expand Up @@ -43,14 +44,43 @@ class ReviewStatus(str, Enum):


class Lecturer(BaseDbModel):
id: Mapped[int] = mapped_column(Integer, primary_key=True)
first_name: Mapped[str] = mapped_column(String, nullable=False)
last_name: Mapped[str] = mapped_column(String, nullable=False)
middle_name: Mapped[str] = mapped_column(String, nullable=False)
avatar_link: Mapped[str] = mapped_column(String, nullable=True)
id: Mapped[int] = mapped_column(Integer, primary_key=True, comment="Идентификатор преподавателя")
first_name: Mapped[str] = mapped_column(String, nullable=False, comment="Имя препода")
last_name: Mapped[str] = mapped_column(String, nullable=False, comment="Фамилия препода")
middle_name: Mapped[str] = mapped_column(String, nullable=False, comment="Отчество препода")
avatar_link: Mapped[str] = mapped_column(String, nullable=True, comment="Ссылка на аву препода")
timetable_id: Mapped[int]
comments: Mapped[list[Comment]] = relationship("Comment", back_populates="lecturer")
is_deleted: Mapped[bool] = mapped_column(Boolean, nullable=False, default=False)
mark_weighted: Mapped[float] = mapped_column(
Float,
nullable=False,
server_default='0.0',
default=0,
comment="Взвешенная оценка преподавателя, посчитана в dwh",
)
mark_kindness_weighted: Mapped[float] = mapped_column(
Float, nullable=False, server_default='0.0', default=0, comment="Взвешенная оценка доброты, посчитана в dwh"
)
mark_clarity_weighted: Mapped[float] = mapped_column(
Float, nullable=False, server_default='0.0', default=0, comment="Взвешенная оценка понятности, посчитана в dwh"
)
mark_freebie_weighted: Mapped[float] = mapped_column(
Float, nullable=False, server_default='0.0', default=0, comment="Взвешенная оценка халявности, посчитана в dwh"
)
rank: Mapped[int] = mapped_column(
Integer, nullable=False, server_default='0', default=0, comment="Место в рейтинге, посчитана в dwh"
)
rank_update_ts: Mapped[datetime.datetime] = mapped_column(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

респект, правильно, что добавил

DateTime,
nullable=False,
server_default=func.now(),
default=datetime.datetime.now(),
comment="Время обновления записи",
)

is_deleted: Mapped[bool] = mapped_column(
Boolean, nullable=False, default=False, comment="Идентификатор софт делита"
)

@hybrid_method
def search_by_name(self, query: str) -> bool:
Expand Down Expand Up @@ -81,11 +111,15 @@ def order_by_mark(
self, query: str, asc_order: bool
) -> tuple[UnaryExpression[float], InstrumentedAttribute, InstrumentedAttribute]:
if "mark_weighted" in query:
comments_num = func.count(self.comments).filter(Comment.review_status == ReviewStatus.APPROVED)
lecturer_mark_general = func.avg(Comment.mark_general).filter(
Comment.review_status == ReviewStatus.APPROVED
)
expression = calc_weighted_mark(lecturer_mark_general, comments_num, Lecturer.mean_mark_general())
expression = self.mark_weighted
elif "mark_clarity_weighted" in query:
expression = self.mark_clarity_weighted
elif "mark_freebie_weighted" in query:
expression = self.mark_freebie_weighted
elif "mark_kindness_weighted" in query:
expression = self.mark_kindness_weighted
elif "rank" in query:
expression = self.rank
else:
expression = func.avg(getattr(Comment, query)).filter(Comment.review_status == ReviewStatus.APPROVED)
if not asc_order:
Expand All @@ -98,21 +132,6 @@ def order_by_name(
) -> tuple[UnaryExpression[str] | InstrumentedAttribute, InstrumentedAttribute]:
return (getattr(Lecturer, query) if asc_order else getattr(Lecturer, query).desc()), Lecturer.id

@staticmethod
def mean_mark_general() -> float:
mark_general_rows = (
db.session.query(func.avg(Comment.mark_general))
.filter(Comment.review_status == ReviewStatus.APPROVED)
.group_by(Comment.lecturer_id)
.all()
)
mean_mark_general = float(
sum(mark_general_row[0] for mark_general_row in mark_general_rows) / len(mark_general_rows)
if len(mark_general_rows) != 0
else 0
)
return mean_mark_general


class Comment(BaseDbModel):
uuid: Mapped[uuid.UUID] = mapped_column(UUID, primary_key=True, default=uuid.uuid4)
Expand Down
Loading