22from os_vars import get_ieds_table_name
33from common .aws_dynamodb import get_dynamodb_table
44from common .clients import logger , dynamodb_client
5+ from utils import log_status , BATCH_SIZE
56from exceptions .id_sync_exception import IdSyncException
67
78ieds_table = None
@@ -16,23 +17,18 @@ def get_ieds_table():
1617 return ieds_table
1718
1819
19- BATCH_SIZE = 25
20-
21-
2220def ieds_update_patient_id (old_id : str , new_id : str , items_to_update : list | None = None ) -> dict :
2321 """Update the patient ID in the IEDS table."""
2422 logger .info (f"ieds_update_patient_id. Update patient ID from { old_id } to { new_id } " )
2523 if not old_id or not new_id or not old_id .strip () or not new_id .strip ():
26- return { "status" : "error" , "message" : " Old ID and New ID cannot be empty"}
24+ return log_status ( " Old ID and New ID cannot be empty", old_id , "error" )
2725
2826 if old_id == new_id :
29- return { "status" : "success" , "message" : f"No change in patient ID: { old_id } " }
27+ return log_status ( f"No change in patient ID: { old_id } " , old_id )
3028
3129 try :
3230 logger .info (f"Updating patient ID in IEDS from { old_id } to { new_id } " )
3331
34- new_patient_pk = f"Patient#{ new_id } "
35-
3632 if items_to_update is None :
3733 logger .info ("Getting items to update in IEDS table..." )
3834 items_to_update = get_items_from_patient_id (old_id )
@@ -41,64 +37,27 @@ def ieds_update_patient_id(old_id: str, new_id: str, items_to_update: list | Non
4137
4238 if not items_to_update :
4339 logger .warning (f"No items found to update for patient ID: { old_id } " )
44- return {
45- "status" : "success" ,
46- "message" : f"No items found to update for patient ID: { old_id } "
47- }
48-
49- transact_items = []
40+ return log_status (f"No items found to update for patient ID: { old_id } " , old_id )
5041
5142 logger .info (f"Items to update: { len (items_to_update )} " )
52- ieds_table_name = get_ieds_table_name ()
53- for item in items_to_update :
54- transact_items .append ({
55- 'Update' : {
56- 'TableName' : ieds_table_name ,
57- 'Key' : {
58- 'PK' : {'S' : item ['PK' ]},
59- },
60- 'UpdateExpression' : 'SET PatientPK = :new_val' ,
61- 'ExpressionAttributeValues' : {
62- ':new_val' : {'S' : new_patient_pk }
63- }
64- }
65- })
66-
67- logger .info ("Transacting items in IEDS table..." )
68- # success tracking
69- all_batches_successful = True
70- total_batches = 0
7143
72- # Batch transact in chunks of BATCH_SIZE
73- for i in range (0 , len (transact_items ), BATCH_SIZE ):
74- batch = transact_items [i :i + BATCH_SIZE ]
75- total_batches += 1
76- logger .info (f"Transacting batch { total_batches } of size: { len (batch )} " )
44+ # Build transact items and execute them in batches via helpers to keep
45+ # the top-level function easy to read and test.
46+ transact_items = build_transact_items (old_id , new_id , items_to_update )
7747
78- response = dynamodb_client .transact_write_items (TransactItems = batch )
79- logger .info ("Batch update complete. Response: %s" , response )
80-
81- # Check each batch response
82- if response ['ResponseMetadata' ]['HTTPStatusCode' ] != 200 :
83- all_batches_successful = False
84- logger .error (
85- f"Batch { total_batches } failed with status: { response ['ResponseMetadata' ]['HTTPStatusCode' ]} " )
48+ all_batches_successful , total_batches = execute_transaction_in_batches (transact_items )
8649
8750 # Consolidated response handling
8851 logger .info (
8952 f"All batches complete. Total batches: { total_batches } , All successful: { all_batches_successful } " )
9053
9154 if all_batches_successful :
92- return {
93- "status" : "success" ,
94- "message" :
95- f"IEDS update, patient ID: { old_id } =>{ new_id } . { len (items_to_update )} updated { total_batches } ."
96- }
55+ return log_status (
56+ f"IEDS update, patient ID: { old_id } =>{ new_id } . { len (items_to_update )} updated { total_batches } ." ,
57+ old_id ,
58+ )
9759 else :
98- return {
99- "status" : "error" ,
100- "message" : f"Failed to update some batches for patient ID: { old_id } "
101- }
60+ return log_status (f"Failed to update some batches for patient ID: { old_id } " , old_id , "error" )
10261
10362 except Exception as e :
10463 logger .exception ("Error updating patient ID" )
@@ -184,3 +143,59 @@ def extract_patient_resource_from_item(item: dict) -> dict | None:
184143 return response
185144
186145 return None
146+
147+
148+ def build_transact_items (old_id : str , new_id : str , items_to_update : list ) -> list :
149+ """Construct the list of TransactItems for DynamoDB TransactWriteItems.
150+
151+ Each item uses a conditional expression to ensure PatientPK hasn't changed
152+ since it was read.
153+ """
154+ transact_items = []
155+ ieds_table_name = get_ieds_table_name ()
156+ new_patient_pk = f"Patient#{ new_id } "
157+
158+ for item in items_to_update :
159+ old_patient_pk = item .get ('PatientPK' , f"Patient#{ old_id } " )
160+
161+ transact_items .append ({
162+ 'Update' : {
163+ 'TableName' : ieds_table_name ,
164+ 'Key' : {
165+ 'PK' : {'S' : item ['PK' ]},
166+ },
167+ 'UpdateExpression' : 'SET PatientPK = :new_val' ,
168+ "ConditionExpression" : "PatientPK = :expected_old" ,
169+ 'ExpressionAttributeValues' : {
170+ ':new_val' : {'S' : new_patient_pk },
171+ ':expected_old' : {'S' : old_patient_pk }
172+ }
173+ }
174+ })
175+
176+ return transact_items
177+
178+
179+ def execute_transaction_in_batches (transact_items : list ) -> tuple :
180+ """Execute transact write items in batches of BATCH_SIZE.
181+
182+ Returns (all_batches_successful: bool, total_batches: int).
183+ """
184+ all_batches_successful = True
185+ total_batches = 0
186+
187+ for i in range (0 , len (transact_items ), BATCH_SIZE ):
188+ batch = transact_items [i :i + BATCH_SIZE ]
189+ total_batches += 1
190+ logger .info (f"Transacting batch { total_batches } of size: { len (batch )} " )
191+
192+ response = dynamodb_client .transact_write_items (TransactItems = batch )
193+ logger .info ("Batch update complete. Response: %s" , response )
194+
195+ # Check each batch response
196+ if response ['ResponseMetadata' ]['HTTPStatusCode' ] != 200 :
197+ all_batches_successful = False
198+ logger .error (
199+ f"Batch { total_batches } failed with status: { response ['ResponseMetadata' ]['HTTPStatusCode' ]} " )
200+
201+ return all_batches_successful , total_batches
0 commit comments