Skip to content

Commit e51ba74

Browse files
Adding Oracle markdown doc and docstrings and fixing spelling
1 parent be356ac commit e51ba74

File tree

4 files changed

+162
-16
lines changed

4 files changed

+162
-16
lines changed

docs/utility-guides/Oracle.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Utility Guide: Oracle
2+
3+
The Oracle Utility can be used to run SQL queries or stored procedures on the Oracle database.
4+
5+
## Table of Contents
6+
7+
- [Utility Guide: Oracle](#utility-guide-oracle)
8+
- [Table of Contents](#table-of-contents)
9+
- [Using the Oracle Utility](#using-the-oracle-utility)
10+
- [Required arguments](#required-arguments)
11+
- [Example usage](#example-usage)
12+
- [Oracle Specific Functions](#oracle-specific-functions)
13+
- [Example Usage](#example-usage-1)
14+
15+
## Using the Oracle Utility
16+
17+
To use the Oracle Utility, import the 'OracleDB' class into your test file and then call the DateTimeUtils
18+
methods from within your tests, as required.
19+
20+
## Required arguments
21+
22+
The functions in this class require different arguments.<br>
23+
Look at the docstrings for each function to see what arguments are required.<br>
24+
The docstrings also specify when arguments are optional, and what the default values are when no argument is provided.
25+
26+
## Example usage
27+
28+
from utils.oracle.oracle import OracleDB
29+
30+
def test_oracle_query() -> None:
31+
32+
query = """select column_a,
33+
column_b,
34+
column_c
35+
from example_table
36+
where condition_1 = :condition1
37+
and condition_2 = :condition2"""
38+
39+
params = {
40+
"condition1": 101,
41+
"condition2": 202,
42+
}
43+
44+
result_df = OracleDB().execute_query(query, params)
45+
46+
def run_stored_procedure() -> None:
47+
48+
OracleDB().execute_stored_procedure("bcss_timed_events")
49+
50+
## Oracle Specific Functions
51+
52+
This contains SQL queries that can be used to run tests.<br>
53+
These are all stored in one location to make it easier to edit the query at a later date and to make it accessible to multiple tests.
54+
55+
Common values are placed in the `SqlQueryValues` class to avoid repeating the same values in the queries.
56+
57+
## Example Usage
58+
59+
from oracle.oracle import OracleDB
60+
61+
def example_query() -> pd.DataFrame:
62+
63+
example_df = OracleDB().execute_query(
64+
f"""subject_nhs_number
65+
from ep_subject_episode_t
66+
where se.latest_event_status_id in ({SqlQueryValues.S10_EVENT_STATUS}, {SqlQueryValues.S19_EVENT_STATUS})""")
67+
68+
return example_df

tests/smokescreen/bcss_smokescreen_tests.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
c3_fit_kit_normal_result=75
2121
c3_fit_kit_abnormal_result=150
2222
c3_fit_kit_analyser_code=UU2_tdH3
23-
c3_total_fit_kits_to_retieve=9
23+
c3_total_fit_kits_to_retrieve=9
2424
c3_fit_kit_authorised_user=AUTO1
2525

2626
# ----------------------------------

utils/oracle/oracle.py

Lines changed: 45 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ def __init__(self):
1616
def connect_to_db(self) -> oracledb.Connection:
1717
"""
1818
This function is used to connect to the Oracle DB. All the credentials are retrieved from a .env file
19+
20+
Returns:
21+
conn (oracledb.Connection): The Oracle DB connection object
1922
"""
2023
try:
2124
logging.info("Attempting DB connection...")
@@ -29,17 +32,26 @@ def connect_to_db(self) -> oracledb.Connection:
2932
f"Failed to to extract subject ID with error: {queryExecutionError}"
3033
)
3134

32-
def disconnect_from_db(self, conn) -> None:
35+
def disconnect_from_db(self, conn: oracledb.Connection) -> None:
36+
"""
37+
Disconnects from the DB
38+
39+
Args:
40+
conn (oracledb.Connection): The Oracle DB connection object
41+
"""
3342
conn.close()
3443
logging.info("Connection Closed")
3544

3645
def exec_bcss_timed_events(
37-
self, nhs_number_df
46+
self, nhs_number_df: pd.DataFrame
3847
) -> None: # Executes bcss_timed_events when given NHS numbers
3948
"""
40-
this function is used to execute bcss_timed_events against NHS Numbers.
49+
This function is used to execute bcss_timed_events against NHS Numbers.
4150
It expects the nhs_numbers to be in a dataframe, and runs a for loop to get the subject_screening_id for each nhs number
4251
Once a subject_screening_id is retrieved, it will then run the command: exec bcss_timed_events [<subject_id>,'Y']
52+
53+
Args:
54+
nhs_number_df (pd.DataFrame): A dataframe containing all of the NHS numbers as separate rows
4355
"""
4456
conn = self.connect_to_db()
4557
try:
@@ -66,9 +78,15 @@ def exec_bcss_timed_events(
6678
if conn is not None:
6779
self.disconnect_from_db(conn)
6880

69-
def get_subject_id_from_nhs_number(self, nhs_number) -> str:
81+
def get_subject_id_from_nhs_number(self, nhs_number: str) -> str:
7082
"""
7183
This function is used to obtain the subject_screening_id of a subject when given an nhs number
84+
85+
Args:
86+
nhs_number (str): The NHS number of the subject
87+
88+
Returns:
89+
subject_id (str): The subject id for the provided nhs number
7290
"""
7391
conn = self.connect_to_db()
7492
logging.info(f"Attempting to get subject_id from nhs number: {nhs_number}")
@@ -86,6 +104,9 @@ def populate_ui_approved_users_table(
86104
) -> None: # To add users to the UI_APPROVED_USERS table
87105
"""
88106
This function is used to add a user to the UI_APPROVED_USERS table
107+
108+
Args:
109+
user (str): The user you want to add to the table
89110
"""
90111
conn = self.connect_to_db()
91112
try:
@@ -131,11 +152,22 @@ def execute_query(
131152
"""
132153
This is used to execute any sql queries.
133154
A query is provided and then the result is returned as a pandas dataframe
155+
156+
Args:
157+
query (str): The SQL query you wish to run
158+
parameters (list | None): Optional - Any parameters you want to pass on in a list
159+
160+
Returns:
161+
df (pd.DataFrame): A pandas dataframe of the result of the query
134162
"""
135163
conn = self.connect_to_db()
136164
engine = create_engine("oracle+oracledb://", creator=lambda: conn)
137165
try:
138-
df = pd.read_sql(query, engine) if parameters == None else pd.read_sql(query, engine, params = parameters)
166+
df = (
167+
pd.read_sql(query, engine)
168+
if parameters == None
169+
else pd.read_sql(query, engine, params=parameters)
170+
)
139171
except Exception as executionError:
140172
logging.error(
141173
f"Failed to execute query with execution error {executionError}"
@@ -151,6 +183,9 @@ def execute_stored_procedure(
151183
"""
152184
This is to be used whenever we need to execute a stored procedure.
153185
It is provided with the stored procedure name and then executes it
186+
187+
Args:
188+
procedure (str): The stored procedure you want to run
154189
"""
155190
conn = self.connect_to_db()
156191
try:
@@ -168,11 +203,15 @@ def execute_stored_procedure(
168203
self.disconnect_from_db(conn)
169204

170205
def update_or_insert_data_to_table(
171-
self, statement, params
206+
self, statement: str, params: list
172207
) -> None: # To update or insert data into a table
173208
"""
174209
This is used to update or insert data into a table.
175210
It is provided with the SQL statement along with the arguments
211+
212+
Args:
213+
statement (str): The SQL query you wish to run
214+
params (list | None): Any parameters you want to pass on in a list
176215
"""
177216
conn = self.connect_to_db()
178217
try:

utils/oracle/oracle_specific_functions.py

Lines changed: 48 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,14 @@ def get_kit_id_from_db(
1919
) -> pd.DataFrame:
2020
"""
2121
This query is used to obtain test kits used in compartment 2
22-
It searches for kits that have not been logged and meet the following criteria:
23-
- tk.tk_type_id = 2 (Only FIT Kits)
24-
- sdc.hub_id = 23159 (Hub ID that the compartments are running in)
25-
- se.latest_event_status_id is 11198 or 11213 (Only kits at the status we want S10/S19 are retrieved)
22+
23+
Args:
24+
tk_type_id (int): The id of the kit type
25+
hub_id (int): The hub ID of the screening center
26+
no_of_kits_to_retrieve (int): The amount of kits you want to retrieve
27+
28+
Returns:
29+
kit_id_df (pd.DataFrame): A pandas DataFrame containing the result of the query
2630
"""
2731
logging.info("Retrieving useable test kit ids")
2832
kit_id_df = OracleDB().execute_query(
@@ -43,10 +47,16 @@ def get_kit_id_from_db(
4347
return kit_id_df
4448

4549

46-
def get_nhs_no_from_batch_id(batch_id) -> pd.DataFrame:
50+
def get_nhs_no_from_batch_id(batch_id: str) -> pd.DataFrame:
4751
"""
4852
This query returns a dataframe of NHS Numbers of the subjects in a certain batch
4953
We provide the batch ID e.g. 8812 and then we have a list of NHS Numbers we can verify the statuses
54+
55+
Args:
56+
batch_id (str): The batch ID you want to get the subjects from
57+
58+
Returns:
59+
nhs_number_df (pd.DataFrame): A pandas DataFrame containing the result of the query
5060
"""
5161
nhs_number_df = OracleDB().execute_query(
5262
f"""
@@ -66,9 +76,12 @@ def get_nhs_no_from_batch_id(batch_id) -> pd.DataFrame:
6676
def get_kit_id_logged_from_db(smokescreen_properties: dict) -> pd.DataFrame:
6777
"""
6878
This query is used to obtain test data used in compartment 3
69-
It searches for kits that have not been logged and meet the following criteria:
70-
- tk.tk_type_id = 2 (Only FIT Kits)
71-
- tk.logged_in_at = 23159 (Hub ID that the compartments are running in)
79+
80+
Args:
81+
smokescreen_properties(): A dictionary containing all values needed to run the query
82+
83+
Returns:
84+
return kit_id_df (pd.DataFrame): A pandas DataFrame containing the result of the query
7285
"""
7386
kit_id_df = OracleDB().execute_query(
7487
f"""SELECT tk.kitid,tk.device_id,tk.screening_subject_id
@@ -83,7 +96,7 @@ def get_kit_id_logged_from_db(smokescreen_properties: dict) -> pd.DataFrame:
8396
AND tk.logged_in_at = {smokescreen_properties["c3_fit_kit_results_test_org_id"]}
8497
AND tk.reading_flag = 'N'
8598
AND tk.test_results IS NULL
86-
fetch first {smokescreen_properties["c3_total_fit_kits_to_retieve"]} rows only
99+
fetch first {smokescreen_properties["c3_total_fit_kits_to_retrieve"]} rows only
87100
"""
88101
)
89102

@@ -93,6 +106,12 @@ def get_kit_id_logged_from_db(smokescreen_properties: dict) -> pd.DataFrame:
93106
def get_service_management_by_device_id(device_id: str) -> pd.DataFrame:
94107
"""
95108
This SQL is similar to the one used in pkg_test_kit_queue.p_get_fit_monitor_details, but adapted to allow us to pick out sub-sets of records
109+
110+
Args:
111+
device_id (str): The device ID
112+
113+
Returns:
114+
get_service_management_df (pd.DataFrame): A pandas DataFrame containing the result of the query
96115
"""
97116

98117
query = """SELECT kq.device_id, kq.test_kit_name, kq.test_kit_type, kq.test_kit_status,
@@ -136,6 +155,14 @@ def update_kit_service_management_entity(
136155
"""
137156
This method is used to update the KIT_QUEUE table on the DB
138157
This is done so that we can then run two stored procedures to update the subjects and kits status to either normal or abnormal
158+
159+
Args:
160+
device_id (str): The device ID
161+
normal (bool): Whether the device should be marked as normal or abnormal
162+
smokescreen_properties(): A dictionary containing all values needed to run the query
163+
164+
Returns:
165+
subject_nhs_number (str): The NHS Number of the affected subject
139166
"""
140167
get_service_management_df = get_service_management_by_device_id(device_id)
141168

@@ -229,6 +256,12 @@ def get_subjects_for_appointments(subjects_to_retrieve: int) -> pd.DataFrame:
229256
This is used to get subjects for compartment 4
230257
It finds subjects with open episodes and the event status A8
231258
It also checks that the episode is less than 2 years old
259+
260+
Args:
261+
subjects_to_retrieve (int): The number of subjects to retrieve
262+
263+
Returns:
264+
subjects_df (pd.DataFrame): A pandas DataFrame containing the result of the query
232265
"""
233266
subjects_df = OracleDB().execute_query(
234267
f"""
@@ -257,6 +290,12 @@ def get_subjects_with_booked_appointments(subjects_to_retrieve: int) -> pd.DataF
257290
This is used to get subjects for compartment 5
258291
It finds subjects with appointments book and letters sent
259292
and makes sure appointments are prior to todays date
293+
294+
Args:
295+
subjects_to_retrieve (int): The number of subjects to retrieve
296+
297+
Returns:
298+
subjects_df (pd.DataFrame): A pandas DataFrame containing the result of the query
260299
"""
261300
subjects_df = OracleDB().execute_query(
262301
f"""

0 commit comments

Comments
 (0)