Python实现SQLite3客户录入系统出生日期格式校验与无效数据入库拦截
问题根因
- 当前的校验逻辑和写入流程完全脱节:
validate()方法检测到日期格式错误时,仅会弹出错误提示,弹窗结束后方法会正常返回None,不会传递任何校验失败的信号给AddCustomer,因此后续的数据库写入操作完全不受阻断,无论校验是否通过都会执行。 - 存在隐性的格式匹配错误:原代码中用于解析日期的格式串
'%D/%M/%Y'使用了错误的占位符——%D是美式斜杠短日期的别名、%M对应分钟字段,和提示要求的DD-MM-YYYY格式完全不匹配,后续就算修好流程阻断逻辑,也会出现合法日期被误判的问题。
修复实现
两种方案都可以实现校验失败即中断写入的效果,按需选择即可:
方案1:校验方法返回状态值,失败时直接终止流程
修改validate方法,在校验通过时返回True,校验失败弹窗后返回False,在主写入逻辑中判断返回值,校验不通过就直接退出方法,不执行任何数据库操作。
修改后的validate方法:
def validate(self): dateofbirth = self.DOBEntry.get().strip() try: # 替换为正确的日期占位符,匹配DD-MM-YYYY的输入要求 datetime.datetime.strptime(dateofbirth, '%d-%m-%Y') return True except ValueError: tkinter.messagebox.showerror("Error","Please enter the date of birth in the correct format DD-MM-YYYY") return False
在AddCustomer方法的写库逻辑前增加判断:
try: # 校验不通过直接return,后续写库代码完全不执行 if not self.validate(): return # 以下原有数据库写入、成功提示、清空表单的逻辑无需修改 with sqlite3.connect("LeeOpt.db") as db: cursor = db.cursor() add_customer = '''INSERT INTO Customer(CustomerID, BranchID, Name, Surname, DateOfBirth, Town, Postcode, EmailAddress, TelephoneNo, MedicalConditions) VALUES (?,?,?,?,?,?,?,?,?,?)''' cursor.execute(add_customer, [customerid, branchid, name, surname, dateofbirth, town, postcode, email, telephone, medical]) tkinter.messagebox.showinfo("Notification","Customer added successfully") self.ClearEntries() except (sqlite3.IntegrityError): tkinter.messagebox.showerror("Error","This CustomerID is already taken, please try another.") self.ClearID()
方案2:校验失败时主动抛出异常,依托现有异常机制阻断流程
如果不想在主逻辑中增加额外的判断分支,可以在校验失败时主动抛出异常,让当前的try-except结构拦截异常,中断执行流程:
- 修改
validate方法,在格式错误弹窗后主动抛出ValueError:
def validate(self): dateofbirth = self.DOBEntry.get().strip() try: datetime.datetime.strptime(dateofbirth, '%d-%m-%Y') except ValueError: tkinter.messagebox.showerror("Error","Please enter the date of birth in the correct format DD-MM-YYYY") # 抛出异常中断后续执行 raise ValueError("Invalid date format")
- 扩展
AddCustomer方法的异常捕获范围,避免校验类异常触发Tkinter默认的错误回溯弹窗:
# 原异常捕获仅覆盖数据库完整性错误,需新增ValueError类型 except (sqlite3.IntegrityError, ValueError) as e: # 对不同类型的错误做区分处理 if isinstance(e, sqlite3.IntegrityError): tkinter.messagebox.showerror("Error","This CustomerID is already taken, please try another.") self.ClearID() # 日期格式错误的提示已经在validate方法中弹出,无需重复提示
内容的提问来源于stack exchange,提问作者rbeatt
相关产品推荐
相关产品推荐

