You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
criteria=criteria_dict, # Dict[str, str] of selection criteria
46
47
user=test_user, # User object
47
-
subject=test_subject, # Subject object (can be None)
48
+
subject=test_subject, # Subject object
48
49
subjects_to_retrieve=100# Optional limit
49
50
)
50
51
```
52
+
51
53
When you call `build_subject_selection_query(...)`, it returns a tuple containing:
52
54
53
55
`query` — a complete SQL string with placeholders like :nhs_number, ready to be run against the database.
@@ -62,11 +64,11 @@ This approach ensures injection-safe execution (defending against SQL injection
62
64
63
65
```python
64
66
criteria = {
65
-
"NHS_NUMBER": "1234567890",
66
-
"SCREENING_STATUS": "invited"
67
+
"nhs_number": "1234567890",
68
+
"screening_status": "invited"
67
69
}
68
70
69
-
user = User(user_id=42, organisation=None) #Simulated user
71
+
user = User(user_id=42, organisation=None) #Optional; used for 'unchanged' logic
70
72
subject = Subject() # Optional; used for 'unchanged' logic
71
73
72
74
builder = SubjectSelectionQueryBuilder()
@@ -86,6 +88,7 @@ WHERE 1=1
86
88
ANDss.screening_status_id=1001
87
89
FETCH FIRST 1 ROWS ONLY
88
90
```
91
+
89
92
(Note: 1001 would be the resolved ID for "invited" in ScreeningStatusType.)
90
93
91
94
#### bind_vars
@@ -101,7 +104,8 @@ FETCH FIRST 1 ROWS ONLY
101
104
You can pass both values directly into your DB layer or test stub:
102
105
103
106
```python
104
-
cursor.execute(query, bind_vars)
107
+
from utils.oracle.oracle import OracleDB
108
+
df = OracleDB().execute_query(query, bind_vars)
105
109
```
106
110
107
111
## Supported Inputs
@@ -118,11 +122,12 @@ Example:
118
122
119
123
```python
120
124
{
121
-
"SUBJECT_HAS_EVENT_STATUS": "ES01",
122
-
"SUBJECT_AGE": "> 60",
123
-
"DATE_OF_DEATH": "null"
125
+
"subject_has_event_status": "ES01",
126
+
"subject_age": "> 60",
127
+
"date_of_death": "null"
124
128
}
125
129
```
130
+
126
131
Each of those triggers a different clause in the generated SQL.
127
132
128
133
### 2. user (User)
@@ -136,16 +141,19 @@ Example:
136
141
```python
137
142
"SUBJECT_HUB_CODE": "USER_HUB"
138
143
```
144
+
139
145
This means “filter by the hub assigned to this user’s organisation,” not a fixed hub like ABC.
140
146
141
147
### 3. subject (Subject)
148
+
142
149
This is used when a filter wants to compare the current value in the database to an existing value on file—often represented by the "UNCHANGED" keyword.
143
150
144
151
Example:
145
152
146
153
```python
147
154
"SCREENING_STATUS": "unchanged"
148
155
```
156
+
149
157
That’s saying: “Only return subjects whose screening status has not changed compared to what’s currently recorded on the subject object.”
150
158
151
159
Without a subject, "unchanged" logic isn’t possible and will raise a validation error.
@@ -164,11 +172,10 @@ Joins to related datasets are added dynamically only when required (e.g. latest
164
172
165
173
All dates are handled via Oracle `TRUNC(SYSDATE)` and `TO_DATE()` expressions to ensure consistent date logic.
166
174
167
-
168
175
## Reference
169
176
170
177
For a full list of supported `SubjectSelectionCriteriaKey` values and expected inputs, refer to the enumeration in:
171
178
172
179
`classes/subject_selection_criteria_key.py`
173
180
174
-
Or explore the full `SubjectSelectionQueryBuilder._dispatch_criteria_key()` method to review how each key is implemented.
181
+
Or explore the full `SubjectSelectionQueryBuilder._dispatch_criteria_key()` method to review how each key is implemented.
0 commit comments