使用scoped_session在事务内调取commit方法报sqlalchemy.exc.ResourceClosedError: This transaction is closed
时间: 2024-03-15 22:45:48 浏览: 15
`scoped_session` 通常用于管理会话的生命周期,它会为每个线程创建一个会话,并在线程结束时自动关闭会话。但是,如果你在使用 `scoped_session` 时手动控制事务,可能会遇到这个问题。
这个错误通常是由于在事务关闭后尝试使用连接或事务引起的。在使用 `scoped_session` 进行数据库操作时,需要注意在适当的时候提交事务,否则会引起这个错误。你可以尝试在事务内调用 `commit` 方法,如下所示:
```python
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy import create_engine
engine = create_engine('mysql://user:password@localhost/db_name')
Session = scoped_session(sessionmaker(bind=engine))
session = Session()
try:
# 在事务内进行数据库操作
session.add(...)
session.commit()
except:
session.rollback()
raise
finally:
# 在事务结束后关闭会话
session.close()
```
在这个例子中,我们手动控制了事务,确保在事务结束时调用了 `commit` 方法,并在 `finally` 块中关闭了会话。
相关问题
AttributeError: 'scoped_session' object has no attribute '_autoflush'
这个错误通常发生在使用 SQLAlchemy ORM 操作数据库时。它表示你正在尝试在一个被标记为 "scoped_session" 的会话上执行一个不受支持的操作。
一个可能的解决方法是在创建 "scoped_session" 对象时,将参数 autoflush 设置为 True,如下所示:
```
from sqlalchemy.orm import scoped_session, sessionmaker
Session = scoped_session(sessionmaker(autoflush=True))
```
如果你已经创建了 "scoped_session" 对象,你可以尝试手动设置 autoflush 属性,如下所示:
```
from sqlalchemy.orm import scoped_session
session = scoped_session(...)
session.autoflush = True
```
这应该能够解决该错误。如果问题仍然存在,请提供更多的上下文信息,以便我能够帮助你更好地解决问题。
app.route('/deleteaccount/<int:account_id>', methods=['POST']) @login_required def delete_account(account_id) : authed = session.get('authed') if not authed : return redirect(url_for('login')) form1 = DeleteAccountForm() account = User.query.get_or_404(account_id) if form1.submit.data and form1.validate() : if current_user.id != account.id : abort(401) flash('Usurpation') logout_user() db.session.delete(account) db.session.commit() session.pop('authed') flash('Disposed') else : abort(400) return redirect(url_for('login')) @db.event.listens_for(User, 'after_delete', named=True) def edit_account(**kwargs) : target = kwargs['target'] for username in [target.username] : if username is not None : dis = Photo.query.filter_by(user_name=username).delete() db.session.begin(subtransactions=True) db.session.commit() ,报错信息:TypeError: scoped_session.begin() got an unexpected keyword argument 'subtransactions',修改报错
在你的代码中,`scoped_session` 不支持 `subtransactions` 参数。你可以使用 `session.begin_nested()` 代替 `scoped_session.begin(subtransactions=True)`,以实现嵌套事务。
以下是修改后的代码:
```
@app.route('/deleteaccount/<int:account_id>', methods=['POST'])
@login_required
def delete_account(account_id):
authed = session.get('authed')
if not authed:
return redirect(url_for('login'))
form1 = DeleteAccountForm()
account = User.query.get_or_404(account_id)
if form1.submit.data and form1.validate():
if current_user.id != account.id:
abort(401)
flash('Usurpation')
logout_user()
db.session.delete(account)
db.session.commit()
session.pop('authed')
flash('Disposed')
else:
abort(400)
return redirect(url_for('login'))
@db.event.listens_for(User, 'after_delete', named=True)
def edit_account(**kwargs):
target = kwargs['target']
for username in [target.username]:
if username is not None:
dis = Photo.query.filter_by(user_name=username).delete()
nested = db.session.begin_nested()
nested.commit()
```