Python SQL数据库查询与决策逻辑优化问题咨询
程序优化方案与代码重构
核心问题分析
- 重复创建账号:原代码中查询结果为
None时,执行WebDAT.CreateAcct()后未终止函数,后续代码仍会执行;且未在创建前做二次校验,并发场景下易导致重复创建。 - SQL注入风险:直接用字符串格式化拼接SQL语句,存在安全隐患。
- 代码冗余:大量
elif分支处理账号映射,维护成本高。 - 资源管理不规范:未自动关闭数据库连接/游标,可能导致资源泄漏。
- 逻辑错误:当查询结果为
None时,后续for x in check会触发TypeError(None不可迭代)。
优化步骤与重构代码
优化后的代码
import pyodbc import ADconnect import PassChngWeb import WebDAT # 账号-凭证映射字典,替代冗余elif分支 ACCOUNT_CREDENTIALS = { 'jsparky': ('jsparky', 'IMaLostBoy'), 'JSparky2/': ('JSparky2', 'StillALostBoy'), 'jazzadmin': ('jazzadmin', 'JazzHands'), 'adminMean': ('adminMean', 'TooTheFloor'), 'RogerDat': ('RogerDat', 'ToTheWall'), 'LukeSkyWalker': ('LukeSkyWalker', 'TillTheSweat'), 'SuperKlein': ('SuperKlein', 'DropsDownMy'), 'NoDetention/': ('NoDetention', 'Ballzzzz'), 'Vader': ('Vader', 'IamYouFather'), 'R2D2/': ('R2D2', 'R2D2'), 'BabyYoda': ('BabyYoda', 'FalconX') } def check_account(): sql_email = ADconnect.email driver_name = 'SQL SERVER' server_name = "ServerTime" database_name = 'TimeToParty' connection_string = f""" DRIVER={{{driver_name}}}; SERVER={server_name}; DATABASE={database_name}; Trust_Connection=yes; """ # 使用with语句自动管理连接和游标,无需手动关闭 with pyodbc.connect(connection_string) as conn: with conn.cursor() as cursor: # 参数化查询,避免SQL注入 sql = "SELECT Account_Number FROM DATacc WHERE Email_Address = ?" cursor.execute(sql, (sql_email,)) result = cursor.fetchone() if not result: print("No user account found") # 创建账号前二次校验,防止并发场景重复创建 cursor.execute(sql, (sql_email,)) recheck_result = cursor.fetchone() if not recheck_result: WebDAT.CreateAcct() # 若CreateAcct会写入数据库,需提交事务 conn.commit() return # 创建后终止函数,避免后续逻辑执行 account_number = result[0] print(f"Found account: {account_number}") # 从字典获取凭证,简化逻辑 if account_number in ACCOUNT_CREDENTIALS: admin_user, admin_pwd = ACCOUNT_CREDENTIALS[account_number] print(f"Username: {admin_user}") PassChngWeb.ChangeLogin(admin_user, admin_pwd) else: print(f"Unknown account number: {account_number}")
关键优化点说明
- 解决重复创建账号:
- 创建账号前增加二次查询,避免多进程并发时重复创建同一账号。
- 创建完成后立即
return终止函数,防止后续无效代码执行。 - 若
WebDAT.CreateAcct()会向数据库写入数据,添加conn.commit()确保事务提交。
- 安全与简洁性:
- 用参数化查询替代字符串拼接,彻底避免SQL注入。
- 用字典映射账号与凭证,移除20+行
elif分支,降低维护成本。
- 资源管理:使用
with语句自动管理数据库连接和游标,程序退出时自动释放资源,无需手动调用close()。 - 逻辑修复:移除全局变量,改用局部变量;修复
None迭代的错误;统一变量命名规范,提升可读性。
内容的提问来源于stack exchange,提问作者DaHawg
相关产品推荐
相关产品推荐

