onhuko 2023-01-07 23:45 采纳率: 58.3%
浏览 152
已结题

FLASK SQLAlchemy sqlalchemy.exc.ResourceClosedError: This transaction is closed 报错

问题遇到的现象和发生背景

在学习SQLAlchemy时

遇到的现象和发生背景,请写出第一个错误信息

出现错误 Resource.Closed.Error : this transaction is closed

用代码块功能插入代码,请勿粘贴截图。 不用代码块回答率下降 50%
@db.event.listens_for(User, 'after_delete', named=True)
def delete_account(**kwargs) :
    target =kwargs['target']
    for username in [target.username] :
        if username is not None :
            dis = Photo.query.filter_by(user_name=username).update({'user_name':'Disposed'})
            db.session.commit()
class User(db.Model) :
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(30), unique=True)
    password = db.Column(db.String(30))
    photos = db.relationship('Photo', back_populates='users', cascade='all')


class Photo(db.Model) :
    id = db.Column(db.Integer, primary_key=True)
    photoname =db.Column(db.String(127), unique=True)
    purename = db.Column(db.String(127), unique=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    users = db.relationship('User', back_populates='photos')
    user_name = db.Column(db.String(30), unique=True)
运行结果及详细报错内容

Traceback (most recent call last):
File "/usr/lib/python3.10/code.py", line 90, in runcode
exec(code, self.locals)
File "", line 1, in
File "", line 2, in commit
File "/usr/local/lib/python3.10/dist-packages/sqlalchemy/orm/session.py", line 1451, in commit
self._transaction.commit(_to_root=self.future)
File "/usr/local/lib/python3.10/dist-packages/sqlalchemy/orm/session.py", line 829, in commit
self._prepare_impl()
File "/usr/local/lib/python3.10/dist-packages/sqlalchemy/orm/session.py", line 808, in _prepare_impl
self.session.flush()
File "/usr/local/lib/python3.10/dist-packages/sqlalchemy/orm/session.py", line 3444, in flush
self.flush(objects)
File "/usr/local/lib/python3.10/dist-packages/sqlalchemy/orm/session.py", line 3583, in flush
with util.safe_reraise():
File "/usr/local/lib/python3.10/dist-packages/sqlalchemy/util/langhelpers.py", line 84, in exit
compat.raise
(value, with_traceback=traceback)
File "/usr/local/lib/python3.10/dist-packages/sqlalchemy/util/compat.py", line 210, in raise

raise exception
File "/usr/local/lib/python3.10/dist-packages/sqlalchemy/orm/session.py", line 3584, in _flush
transaction.rollback(_capture_exception=True)
File "/usr/local/lib/python3.10/dist-packages/sqlalchemy/orm/session.py", line 851, in rollback
self._assert_active(prepared_ok=True, rollback_ok=True)
File "/usr/local/lib/python3.10/dist-packages/sqlalchemy/orm/session.py", line 617, in _assert_active
raise sa_exc.ResourceClosedError(closed_msg)
sqlalchemy.exc.ResourceClosedError: This transaction is closed

我的解答思路和尝试过的方法,不写自己思路的,回答率下降 60%

尝试修改Photo表

我想要达到的结果,如果你需要快速回答,请尝试 “付费悬赏”
  • 写回答

8条回答 默认 最新

  • qq_1311209878 2023-01-10 16:55
    关注

    这个错误信息表明你在调用 db.session.commit() 时,会话已经被关闭了。这通常是因为在你之前调用过 db.session.rollback() 或者 db.session.close()。

    在你的代码中,你在 delete_account 函数里调用了 db.session.commit(),但是你并没有在这个函数内部打开一个新的事务。因此,当你尝试在会话已经关闭的情况下调用 commit() 时,会抛出上面这个异常。

    一种可能的解决方法是,在 delete_account 函数内部打开一个新的事务。例如:

    
    ```python
    @db.event.listens_for(User, 'after_delete', named=True)
    def delete_account(**kwargs) :
        target =kwargs['target']
        for username in [target.username] :
            if username is not None :
                dis = Photo.query.filter_by(user_name=username).update({'user_name':'Disposed'})
                db.session.begin()
                db.session.commit()
    
    
    
    需要注意的是, 您使用了SQLAlchemy的事件监听机制来监听 User 模型的after_delete事件,在删除User之后,相关的Photo的user_name会被更新。然而, 您的代码中并没有考虑到在处理这个事件的同时,会话已经被关闭了。
    
    解决方法之一是,确保在你的函数内部打开一个新的事务。 更一般地,你需要确保在所有数据库操作之前会话是打开的,并在所有操作之后关闭会话。
    
    另外需要注意的是,在修改photo表的user_name后, 你需要重新加载photo的信息,或者将其返回到会话中,否则你将在进行其他操作时遇到相似的错误。
    
    ```python
    @db.event.listens_for(User, 'after_delete', named=True)
    def delete_account(**kwargs) :
        target =kwargs['target']
        for username in [target.username] :
            if username is not None :
                dis = Photo.query.filter_by(user_name=username).update({'user_name':'Disposed'})
                db.session.flush()
                #re-load the photo data
                Photo.query.filter_by(user_name='Disposed').all()
    
    
    

    这些修改将有助于消除错误, 但是需要确保其他相关部分不会出现类似的错误。
    如果我的回答对您解决问题有帮助,请您及时采纳,非常感谢。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(7条)

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 1月14日
  • 已采纳回答 1月14日
  • 赞助了问题酬金15元 1月8日
  • 创建了问题 1月7日

悬赏问题

  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥16 mybatis的代理对象无法通过@Autowired装填
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂
  • ¥15 wordpress 产品图片 GIF 没法显示
  • ¥15 求三国群英传pl国战时间的修改方法
  • ¥15 matlab代码代写,需写出详细代码,代价私
  • ¥15 ROS系统搭建请教(跨境电商用途)