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(app) 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: Instanceis not bound to a Session; attribute refresh operation cannot proceed
可能有的人会说,那你不要关闭数据库会话呀,会话关闭了对象当然就无法访问了,因为ORM需要跟踪这个对象,并缓存一些你对它的操作以便在需要时更新到数据库去的,它不是一个简单的对象。
但我现在的需求是:从数据库中查询得到了一个对象实例之后,就想让这个对象与数据库切断联系,SQLAlchemy
有提供这样的方法吗?我必须定义一个具有同样成员的类然后再初始化它?
try:
session.add(app) session.commit() session.close() return user.name
except:
return None
finally:
session.close
执行user.name时,会查询一次数据库,所以不能在这之前关掉session