Coverage for bc/kwai-bc-training/src/kwai_bc_training/trainings/training_schedule_coach_db_query.py: 100%
32 statements
« prev ^ index » next coverage.py v7.11.0, created at 2024-01-01 00:00 +0000
« prev ^ index » next coverage.py v7.11.0, created at 2024-01-01 00:00 +0000
1"""Module that defines a database query for getting the coaches of training schedules."""
3from collections import defaultdict
4from dataclasses import dataclass
5from typing import Self
7from kwai_core.db.database_query import DatabaseQuery
8from kwai_core.db.table_row import JoinedTableRow
9from kwai_core.domain.value_objects.name import Name
10from kwai_core.domain.value_objects.unique_id import UniqueId
11from sql_smith.functions import on
13from kwai_bc_training.coaches._tables import ( # noqa
14 CoachRow,
15 MemberRow,
16 PersonRow,
17)
18from kwai_bc_training.coaches.coach import CoachEntity, CoachIdentifier
19from kwai_bc_training.trainings._tables import TrainingScheduleCoachRow
20from kwai_bc_training.trainings.training_schedule import TrainingScheduleIdentifier
23@dataclass(kw_only=True, frozen=True, slots=True)
24class TrainingScheduleCoachQueryRow(JoinedTableRow):
25 """A data transfer object for the training schedules coach query."""
27 person: PersonRow
28 member: MemberRow
29 coach: CoachRow
30 training_schedule: TrainingScheduleCoachRow
32 def create_coach(self) -> CoachEntity:
33 """Create a coach entity from a row."""
34 return CoachEntity(
35 id=CoachIdentifier(self.coach.id),
36 name=Name(first_name=self.person.firstname, last_name=self.person.lastname),
37 active=self.coach.active == 1,
38 uuid=UniqueId.create_from_string(self.coach.uuid),
39 head=self.coach.head == 1,
40 )
43class TrainingScheduleCoachDbQuery(DatabaseQuery):
44 """A database query for training schedule coaches."""
46 def init(self):
47 self._query.from_(TrainingScheduleCoachRow.__table_name__).left_join(
48 CoachRow.__table_name__,
49 on(TrainingScheduleCoachRow.column("coach_id"), CoachRow.column("id")),
50 ).join(
51 MemberRow.__table_name__,
52 on(CoachRow.column("member_id"), MemberRow.column("id")),
53 ).join(
54 PersonRow.__table_name__,
55 on(MemberRow.column("person_id"), PersonRow.column("id")),
56 )
58 @property
59 def columns(self):
60 return TrainingScheduleCoachQueryRow.get_aliases()
62 def filter_by_schedule(self, *ids: TrainingScheduleIdentifier) -> Self:
63 """Filter by training schedules."""
64 unpacked_ids = tuple(i.value for i in ids)
65 self._query.and_where(
66 TrainingScheduleCoachRow.field("training_schedule_id").in_(*unpacked_ids)
67 )
68 return self
70 async def fetch_coaches(
71 self,
72 ) -> dict[TrainingScheduleIdentifier, list[CoachEntity]]:
73 """Fetch coaches.
75 A specialized fetch method that already transforms the records into a CoachEntity.
77 Returns:
78 A dictionary that contains the list of coaches for the training schedules. The key
79 is the identifier of the schedule.
80 """
81 result: dict[TrainingScheduleIdentifier, list[CoachEntity]] = defaultdict(list)
83 async for row in self.fetch():
84 training_schedule_coach_row = TrainingScheduleCoachQueryRow.map(row)
85 result[
86 TrainingScheduleIdentifier(
87 training_schedule_coach_row.training_schedule.training_schedule_id
88 )
89 ].append(training_schedule_coach_row.create_coach())
91 return result