Python中SQLAlchemy的Session.close()失效问题求助
SQLAlchemy Session.close()后还能查数据的原因及解决
为啥关闭会话后还能查数据?
SQLAlchemy里的Session.close()根本不是销毁会话,它只做这几件事:
- 把会话占有的数据库连接还给连接池
- 清空会话里待提交的脏数据、刚添加/待删除的对象
- 不会删掉会话里已经加载过的对象缓存(也就是identity map)
所以你碰到的情况分两种:
- 关闭后查询同一个ID的用户:直接从缓存里拿之前加载好的对象,连数据库都不会访问
- 要是查询没加载过的新对象:会话会自动重新获取连接继续执行查询——因为
close()只是让会话进入"休眠"状态,不是彻底禁用它
怎么验证?
开启SQLAlchemy的SQL日志就能看到,关闭会话后查询同一个用户,不会生成新的SQL语句。要是想彻底让这个会话无法使用,得用Session.remove()(针对scoped_session创建的会话)或者直接丢弃会话对象。
代码修正示例
如果是用scoped_session(比如Flask-SQLAlchemy中的会话),想彻底终止当前会话,用remove()替代close():
user = Session.query(User).filter_by(id=user_id).first() print("Active Session", {'id': user.id, 'email': user.email} ) Session.commit() Session.remove() # 彻底销毁当前会话实例 # 此时再查询会触发新会话创建,或直接报错(取决于会话配置) try: user = Session.query(User).filter_by(id=user_id).first() print("After removing session", {'id': user.id, 'email': user.email}) except Exception as e: print("Error after removing session:", str(e))
如果是普通的Session实例(手动创建的),关闭后直接置空对象即可:
Session.close() Session = None # 让原会话被垃圾回收,彻底无法使用
内容的提问来源于stack exchange,提问作者pravi
相关产品推荐
相关产品推荐

