Python MySQL项目with块放主菜单及复用connection、cursor合理性咨询
问题解答
1. 主菜单无限循环放在with块中是否合规?
完全合规。
你的程序整个运行周期都需要访问数据库,将循环放在连接、cursor的上下文管理器块内,能保证无论程序是正常退出还是运行中抛出异常,都能自动触发__exit__逻辑关闭连接和cursor,不会出现资源泄漏的问题。
唯一需要注意的点:MySQL默认有wait_timeout参数(默认8小时),空闲超过该时长的连接会被数据库主动断开。如果你的程序需要长时间挂起运行,可以在每次执行数据库操作前加连接有效性检查,断开后自动重连即可。
2. 多个函数复用同一个connection和同一个cursor是否合理?现有实现是否正确?
- 复用同一个connection是完全合理的:频繁创建销毁数据库连接的开销非常高,还容易占满数据库的连接数上限,你的这个认知是正确的,对于单线程的菜单交互类程序,单连接完全可以满足需求。
- 复用同一个cursor不推荐,且你现有的实现存在逻辑错误:
- 你的Cursor类和Database类完全脱节,cursor必须从对应的数据库连接对象创建,不能独立凭空实例化,现有代码无法正常运行。
- 全局复用同一个cursor容易出现前一次查询的残留结果影响后续操作的问题,且cursor本身创建销毁的开销极小,完全不需要全局复用。
- 不需要为每个函数单独创建connection,调整实现逻辑即可,参考优化后的代码结构:
import sys import mysql.connector from mysql.connector import Error class Database: def __init__(self, host, user, password, database): self.host = host self.user = user self.password = password self.database = database self.conn = None def __enter__(self): try: self.conn = mysql.connector.connect( host=self.host, user=self.user, password=self.password, database=self.database ) return self except Error as e: print(f"数据库连接失败: {e}") sys.exit(1) def __exit__(self, exc_type, exc_value, exc_tb): if self.conn and self.conn.is_connected(): self.conn.close() # 连接有效性检查,避免超时断开 def _check_connection(self): if not self.conn.is_connected(): self.conn.reconnect() def function_1(self, query1): self._check_connection() # 每个操作内部创建临时cursor,用完自动关闭 with self.conn.cursor() as cursor: cursor.execute(query1) self.conn.commit() # 可按需返回查询结果 def function_2(self, query2): self._check_connection() with self.conn.cursor() as cursor: cursor.execute(query2) self.conn.commit() def function_3(self, query3): self._check_connection() with self.conn.cursor() as cursor: cursor.execute(query3) self.conn.commit() # 主逻辑 if __name__ == "__main__": # 替换为实际的数据库连接参数 with Database(host="localhost", user="root", password="你的密码", database="你的库名") as db: while True: print("MAIN MENU") option = input("1. function 1\n2. function 2\n3. function 3\n4. Exit\n请输入选项:") if option == '1': db.function_1("SELECT * FROM table1") elif option == '2': db.function_2("UPDATE table2 SET count=count+1 WHERE id=1") elif option == '3': db.function_3("DELETE FROM table3 WHERE is_expired=1") elif option == '4': print("程序退出") sys.exit() else: print("无效选项,请重新输入")
内容的提问来源于stack exchange,提问作者Marcos Tarnoski
相关产品推荐
相关产品推荐

