11import sqlalchemy as sa
2+ import sqlalchemy .orm as so
23from orm_loader .helpers import Base
3- from .episode_joins import overarching_disease_episode
4+ from datetime import date
5+ from typing import Optional
6+ from .episode_joins import overarching_disease_episode , treatment_regimen_with_cycles
47from ...core .materialized import MaterializedViewMixin
58from ...core .constructs import register_construct
69
7- class OverarchingDiseaseEpisodeCols :
8- __table_args__ = {"extend_existing" : True }
9-
10- disease_episode_id = sa .Column (sa .Integer , primary_key = True )
11- person_id = sa .Column (sa .Integer )
12-
13- disease_episode_concept_id = sa .Column (sa .Integer )
14- disease_episode_label = sa .Column (sa .String )
15-
16- disease_episode_start_date = sa .Column (sa .Date )
17- disease_episode_end_date = sa .Column (sa .Date )
18-
19- extent_episode_id = sa .Column (sa .Integer )
20- extent_episode_concept_id = sa .Column (sa .Integer )
21- extent_episode_label = sa .Column (sa .String )
22-
23- extent_start_date = sa .Column (sa .Date )
24- extent_end_date = sa .Column (sa .Date )
25-
2610@register_construct
2711class OverarchingDiseaseEpisodeMV (
28- OverarchingDiseaseEpisodeCols ,
2912 MaterializedViewMixin ,
3013 Base ,
3114):
@@ -41,6 +24,23 @@ class OverarchingDiseaseEpisodeMV(
4124 __mv_index__ = "disease_episode_id"
4225 __deps__ = ()
4326 __tablename__ = __mv_name__
27+ __table_args__ = {"extend_existing" : True }
28+
29+ disease_episode_id : so .Mapped [int ] = so .mapped_column (sa .Integer , primary_key = True )
30+ person_id : so .Mapped [int ] = so .mapped_column (sa .Integer )
31+
32+ disease_episode_concept_id : so .Mapped [int ] = so .mapped_column (sa .Integer )
33+ disease_episode_label : so .Mapped [str ] = so .mapped_column (sa .String )
34+
35+ disease_episode_start_date : so .Mapped [date ] = so .mapped_column (sa .Date )
36+ disease_episode_end_date : so .Mapped [Optional [date ]] = so .mapped_column (sa .Date , nullable = True )
37+
38+ extent_episode_id : so .Mapped [Optional [int ]] = so .mapped_column (sa .Integer , nullable = True )
39+ extent_episode_concept_id : so .Mapped [Optional [int ]] = so .mapped_column (sa .Integer , nullable = True )
40+ extent_episode_label : so .Mapped [Optional [str ]] = so .mapped_column (sa .String , nullable = True )
41+
42+ extent_start_date : so .Mapped [Optional [date ]] = so .mapped_column (sa .Date , nullable = True )
43+ extent_end_date : so .Mapped [Optional [date ]] = so .mapped_column (sa .Date , nullable = True )
4444
4545 def __repr__ (self ) -> str :
4646 if self .has_extent :
@@ -62,4 +62,62 @@ def disease_interval(self):
6262 def extent_interval (self ):
6363 if self .extent_episode_id is None :
6464 return None
65- return (self .extent_start_date , self .extent_end_date )
65+ return (self .extent_start_date , self .extent_end_date )
66+
67+ @register_construct
68+ class TreatmentRegimenCycleMV (
69+ MaterializedViewMixin ,
70+ Base ,
71+ ):
72+ """
73+ Materialized view representing treatment regimens
74+ with optional child treatment cycles.
75+
76+ One row per (treatment_regimen, treatment_cycle?) pair.
77+ """
78+
79+ __mv_name__ = "treatment_regimen_cycle_mv"
80+ __mv_select__ = treatment_regimen_with_cycles .select ()
81+ __mv_index__ = "regimen_episode_id"
82+ __deps__ = ()
83+ __tablename__ = __mv_name__
84+ __table_args__ = {"extend_existing" : True }
85+
86+ regimen_episode_id : so .Mapped [int ] = so .mapped_column (sa .Integer , primary_key = True )
87+ person_id : so .Mapped [int ] = so .mapped_column (sa .Integer )
88+
89+ regimen_episode_concept_id : so .Mapped [int ] = so .mapped_column (sa .Integer )
90+ regimen_episode_label : so .Mapped [str ] = so .mapped_column (sa .String )
91+
92+ regimen_start_date : so .Mapped [date ] = so .mapped_column (sa .Date )
93+ regimen_end_date : so .Mapped [Optional [date ]] = so .mapped_column (sa .Date , nullable = True )
94+
95+ cycle_episode_id : so .Mapped [Optional [int ]] = so .mapped_column (sa .Integer , nullable = True )
96+ cycle_episode_concept_id : so .Mapped [Optional [int ]] = so .mapped_column (sa .Integer , nullable = True )
97+ cycle_episode_label : so .Mapped [Optional [str ]] = so .mapped_column (sa .String , nullable = True )
98+
99+ cycle_start_date : so .Mapped [Optional [date ]] = so .mapped_column (sa .Date , nullable = True )
100+ cycle_end_date : so .Mapped [Optional [date ]] = so .mapped_column (sa .Date , nullable = True )
101+
102+
103+ def __repr__ (self ) -> str :
104+ if self .has_cycle :
105+ return (
106+ f"<TreatmentRegimenCycle "
107+ f"{ self .regimen_episode_id } -> cycle { self .cycle_episode_id } >"
108+ )
109+ return f"<TreatmentRegimenCycle { self .regimen_episode_id } >"
110+
111+ @property
112+ def has_cycle (self ) -> bool :
113+ return self .cycle_episode_id is not None
114+
115+ @property
116+ def regimen_interval (self ):
117+ return (self .regimen_start_date , self .regimen_end_date )
118+
119+ @property
120+ def cycle_interval (self ):
121+ if self .cycle_episode_id is None :
122+ return None
123+ return (self .cycle_start_date , self .cycle_end_date )
0 commit comments