Several Changes, One Outcome · practice
Return One Loan
Returning an item should complete one loan row, not delete its history. The caller knows the loan ID and the text label to store in returned_on.
Open transactions.py. A new return_loan(connection, loan_id, returned_on) stub and this static statement are present:
UPDATE loans
SET returned_on = ?
WHERE id = ? AND returned_on IS NULL;
The first placeholder receives returned_on; the second receives loan_id. The final
Inside return_loan, use one connection context and pass the values separately:
with connection:
result = connection.execute(RETURN_LOAN, (returned_on, loan_id))
changed = result.rowcount == 1
return changed
Read rowcount immediately from this update result. A 1 means this call changed the one active loan. A value of 0 means the ID was absent or its
Press Run. The fixed calls return loan 501, try it again, and try missing ID 9999:
return_loan(connection, 501, '2026-08-26') -> True
return_loan(connection, 501, '2026-08-27') -> False
return_loan(connection, 9999, '2026-08-27') -> False
Fresh connection loan 501 returned_on: 2026-08-26
Connection still open: yes
The second call must not overwrite the first date. Normal context exit commits the successful update and harmless zero-row updates alike. The
Submit uses unseen loan IDs and different return labels. It checks another active loan remains unchanged, reopens the database to prove durability, repeats the operation, and queries through the original connection afterward.
Task
Implement return_loan(connection, loan_id, returned_on) in transactions.py.
Run the supplied parameterized update inside one connection context. Return True only when its immediate rowcount is 1; return False for an absent or already-returned loan. Do not close the connection.