Detached InstanceError:Instance is not bound to a Session 关闭session后使用SQLAlchemy对象

当在关闭数据库会话后尝试访问ORM对象时,会出现DetachedInstanceError。该错误表明对象不再与Session关联。解决方法是在关闭Session前使用session.refresh()刷新对象状态,然后使用session.expunge()将其从Session中移除。这样可以在Session关闭后继续使用对象。另一种方法是将ORM对象转换为普通对象,避免依赖Session。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

DetachedInstanceError: Instance <User at 0x32768d0> is not bound to a Session; attribute refresh operation cannot proceed
搜索了下找到了答案,这种情况主要是发生在 关闭数据库会话后,使用ORM的对用,获取对象的某些字段值,这时就会报错。

报错的原因也很简单,SQLAlchemy的ORM方式将数据库中的记录映射成了我们定义好的模型类,这些类对象的实例只在数据库会话(session)的生命期内有效,假如我们将数据库会话关闭了,再访问数据表类的对象就会报错。类似代码如下:

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
 
Base = declarative_base()
 
 
class User(Base):
    __tablename__ = 'USER'
 
    id = Column(Integer, Sequence('USER_SEQ'), primary_key=True, autoincrement=True)
    name = Column(String(30))
    age = Column(Integer)
    status = Column(String(30))
 
 
engine = create_engine(str(db_url), encoding=b'utf-8', echo=echo, convert_unicode=True)
Session = sessionmaker(bind=engine)
session = Session()
 
user = User(name='John', age=30)
session.add(user)
session.commit()
session.close()
 
print user.name
运行到最后一行会抛出异常:

Traceback (most recent call last):
  File "E:\WorkCopy\test\test.py", line 21, in test_something
    print user.name
  File "C:\Python27\lib\site-packages\sqlalchemy\orm\attributes.py", line 237, in __get__
    return self.impl.get(instance_state(instance), dict_)
  File "C:\Python27\lib\site-packages\sqlalchemy\orm\attributes.py", line 573, in get
    value = state._load_expired(state, passive)
  File "C:\Python27\lib\site-packages\sqlalchemy\orm\state.py", line 480, in _load_expired
    self.manager.deferred_scalar_loader(self, toload)
  File "C:\Python27\lib\site-packages\sqlalchemy\orm\loading.py", line 610, in load_scalar_attributes
    (state_str(state)))
DetachedInstanceError: Instance <User at 0x32768d0> is not bound to a Session; attribute refresh operation cannot proceed
 那么如何在关闭Session 后还可以正常使用这个对象呢? 使用 session.expunge()。

user = User(name='John', age=30)
session.add(user)
session.commit()
 
session.refresh(user)
session.expunge(user)
 
session.close()
 
print user.name
使用 session.refresh(user) 是为了读取自增字段值(如果有的话)到 user 对象

原文链接:https://blog.youkuaiyun.com/mrqingyu/article/details/90372696

 

我用了一个笨办法——将orm对象转换为一个属性相同的普通对象:

class TaskTrackingRecord(db.Model):
    __tablename__ = "task_track"
    __table_args__ = {"extend_existing":True}
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    sub_id = db.Column(db.String(128), nullable=False, unique=False)
    parent_id = db.Column(db.String(128), nullable=True, unique=False)
    root_id = db.Column(db.String(128), nullable=False, unique=False)
    name = db.Column(db.String(128), nullable=False, unique=False)
    call_category = db.Column(db.Integer, nullable=False, unique=False)
    state = db.Column(db.Integer, nullable=False, unique=False)
    timestamp = db.Column(db.Float, nullable=False, unique=False)
    desc = db.Column(db.String(1024), nullable=True, unique=False)

    def __repr__(self):
        return "<%s:%s %s:%s %s>" % (self.parent_id, self.sub_id, CallCategory(self.call_category).name, self.name, StatePoint(self.state).name)

    @property
    def full_name(self):
        return ""

    @staticmethod
    def is_record_exist():
        pass

    def freeze(self):
        """
        :return:
        """
        db.session.refresh(self)
        record = StatusRecord()
        record.sub_id = self.sub_id
        record.root_id = self.root_id
        record.parent_id = self.parent_id
        record.desc = self.desc
        record.state = self.state
        record.call_category = self.call_category
        record.timestamp = self.timestamp
        return record

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值