From 1dcc5e049b521fae67059790e489ae98684972c4 Mon Sep 17 00:00:00 2001 From: MUHAMED FAZAL PS Date: Wed, 24 Jun 2026 13:45:57 +0530 Subject: [PATCH] fix: handle cascade delete when AccessAttemptExpiration table missing reset_user_attempts() calls attempts.delete() which triggers cascade deletion of related AccessAttemptExpiration objects. When the AccessAttemptExpiration migration has not been applied, the table does not exist and the cascade delete raises an error. Fix: wrap delete in try/except, log a warning, and continue. Fixes #1389 --- axes/handlers/database.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/axes/handlers/database.py b/axes/handlers/database.py index 375514e8..08a2adaa 100644 --- a/axes/handlers/database.py +++ b/axes/handlers/database.py @@ -440,8 +440,19 @@ def reset_user_attempts( count = 0 for attempts in attempts_list: - _count, _ = attempts.delete() - count += _count + try: + _count, _ = attempts.delete() + count += _count + except Exception: + # If the AccessAttemptExpiration table does not exist + # (migration not applied), cascade delete will fail. + # Log a warning and continue with remaining attempts. + log.warning( + "AXES: Failed to delete access attempt for %s. " + "This may happen if the AccessAttemptExpiration " + "migration has not been applied.", + attempts, + ) log.info("AXES: Reset %s access attempts from database.", count) return count