Coverage for src/kwai/modules/training/trainings/training_coach_db_query.py: 92%
37 statements
« prev ^ index » next coverage.py v7.6.10, created at 2024-01-01 00:00 +0000
« prev ^ index » next coverage.py v7.6.10, created at 2024-01-01 00:00 +0000
1"""Module that defines a database query to get coaches of training(s)."""
3from collections import defaultdict
4from dataclasses import dataclass
6from sql_smith.functions import on
8from kwai.core.db.database_query import DatabaseQuery
9from kwai.core.db.rows import OwnersTable, OwnerTableRow
10from kwai.core.db.table_row import JoinedTableRow
11from kwai.core.domain.value_objects.name import Name
12from kwai.modules.training.coaches._tables import ( # noqa
13 CoachRow,
14 MemberRow,
15 PersonRow,
16)
17from kwai.modules.training.coaches.coach import CoachEntity, CoachIdentifier
18from kwai.modules.training.trainings.training import TrainingIdentifier
19from kwai.modules.training.trainings.training_tables import (
20 TrainingCoachRow,
21)
22from kwai.modules.training.trainings.value_objects import TrainingCoach
25@dataclass(kw_only=True, frozen=True, slots=True)
26class TrainingCoachQueryRow(JoinedTableRow):
27 """A data transfer object for the training coach query."""
29 training_coach: TrainingCoachRow
30 member: MemberRow
31 person: PersonRow
32 coach: CoachRow
33 owner: OwnerTableRow
35 def create_coach(self) -> TrainingCoach:
36 """Create a training coach from a row."""
37 return TrainingCoach(
38 coach=CoachEntity(
39 id_=CoachIdentifier(self.coach.id),
40 name=Name(
41 first_name=self.person.firstname, last_name=self.person.lastname
42 ),
43 active=self.coach.active == 1,
44 ),
45 owner=self.owner.create_owner(),
46 present=self.training_coach.present == 1,
47 type=self.training_coach.coach_type,
48 payed=self.training_coach.payed == 1,
49 remark=(
50 "" if self.training_coach.remark is None else self.training_coach.remark
51 ),
52 )
55class TrainingCoachDbQuery(DatabaseQuery):
56 """A database query for getting coaches of training(s)."""
58 def init(self):
59 self._query.from_(TrainingCoachRow.__table_name__).left_join(
60 CoachRow.__table_name__,
61 on(TrainingCoachRow.column("coach_id"), CoachRow.column("id")),
62 ).join(
63 MemberRow.__table_name__,
64 on(CoachRow.column("member_id"), MemberRow.column("id")),
65 ).join(
66 PersonRow.__table_name__,
67 on(MemberRow.column("person_id"), PersonRow.column("id")),
68 ).join(
69 OwnersTable.table_name,
70 on(CoachRow.column("user_id"), OwnerTableRow.column("id")),
71 )
73 @property
74 def columns(self):
75 return TrainingCoachQueryRow.get_aliases()
77 def filter_by_trainings(self, *ids: TrainingIdentifier) -> "TrainingCoachDbQuery":
78 """Filter by trainings.
80 Only the rows of the trainings with the given ids, will be returned.
81 """
82 unpacked_ids = tuple(i.value for i in ids)
83 self._query.and_where(TrainingCoachRow.field("training_id").in_(*unpacked_ids))
84 return self
86 async def fetch_coaches(self) -> dict[TrainingIdentifier, list[TrainingCoach]]:
87 """Fetch coaches.
89 A specialized fetch method that already transforms the records into
90 TrainingCoach objects.
92 Returns:
93 A dictionary that contains the list of coaches for trainings. The key
94 is the identifier of a training.
95 """
96 result: dict[TrainingIdentifier, list[TrainingCoach]] = defaultdict(list)
98 async for row in self.fetch():
99 training_coach_row = TrainingCoachQueryRow.map(row)
100 result[
101 TrainingIdentifier(training_coach_row.training_coach.training_id)
102 ].append(training_coach_row.create_coach())
103 return result