执行Python脚本触发AttributeError: __exit__错误该如何解决?
报错根因
- 你使用的Python2版本对应的
MySQLdb库版本较旧,其返回的数据库连接对象没有实现上下文管理器(with语句)要求的__enter__、__exit__方法,所以直接在with语句中调用connect()会抛出AttributeError: __exit__异常。 - 额外存在的逻辑错误:你错误将
connect()返回的数据库连接对象直接当成游标对象使用,执行SQL操作的execute()方法属于游标对象,需要通过连接的cursor()方法单独获取。
修复方案
方法1:手动管理连接和游标(兼容性最好,无需升级依赖)
修改主逻辑块的代码即可:
if __name__ == '__main__': while True: # 手动创建连接和游标 conn = connect('HOST', 'username', 'password', 'database') cur = conn.cursor() try: refresh(cur) # 替换原来的autocommit设置,显式提交事务 conn.commit() finally: # 操作结束后手动关闭资源 cur.close() conn.close() time.sleep(30)
方法2:升级兼容上下文管理器的MySQL驱动
如果不想改现有代码结构,可以将MySQL驱动替换为支持上下文管理器的版本,比如mysqlclient(MySQLdb的后续维护分支),升级后调整游标获取逻辑即可:
if __name__ == '__main__': while True: with connect('HOST', 'username', 'password', 'database') as conn: cur = conn.cursor() refresh(cur) conn.commit() time.sleep(30)
其他需要修复的逻辑问题
- 你代码中的查询条件
WHERE azure_vm.state != 'VM Deleted' and azure_vm.Provisioned = 'api_azure' and azure_app.status != 'failed' or azure_app.status != 'removed'存在逻辑错误:or前后的条件永远有一个成立,会导致筛选逻辑失效,建议调整为正确的优先级,比如把or相关逻辑用括号包裹,或者将or修改为and匹配你实际业务需求。 - 避免在循环中反复设置
cur.autocommit = True,改成在事务结束后显式调用conn.commit()更可控,也能避免部分数据异常提交。
内容的提问来源于stack exchange,提问作者Rajiv
相关产品推荐
相关产品推荐

