Sqlalchemy session.refresh不刷新对象

时间:2013-09-16 14:30:13

标签: python sqlalchemy

我有以下映射(直接来自SA示例):

class User(Base):
    __tablename__ = 'users'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    fullname = Column(String)
    password = Column(String)

我正在使用MySql DB,该表有一个innoDB引擎。

我的表中有一条记录: 1 |'user1'|'user1 test'|'密码'

我用以下代码打开了一个会话:

from sqlalchemy.orm.session import sessionmaker
from sqlalchemy.engine import create_engine
from sqlalchemy.orm.scoping import scoped_session
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

db_engine = create_engine('mysql://...@localhost/test_db?charset=utf8',echo=False,pool_recycle=1800)
session_factory = sessionmaker(bind=db_engine,autocommit=False,autoflush=False)
session_maker = scoped_session(session_factory)
session = session_maker()

user_1 = session.query(User).filter(User.id==1).one()
user_1.name # This prints: u'user1'

现在,当我将数据库中的记录名称更改为“user1_change”并提交它然后像这样刷新对象时:

session.refresh(user_1)
user_1.name # This still prints: u'user1' and not u'user1_change'

它仍会打印:u'user1'而不是u'user1_change'。

我在这里错过了什么(或设置错误?)

谢谢!

4 个答案:

答案 0 :(得分:9)

来自docs

  

请注意,高度隔离的事务将返回与先前在同一事务中读取的值相同的值,而不管该事务之外的数据库状态的更改

SQLAlchemy使用事务工作单元模型,其中假设每个事务在内部是一致的。会话是事务之上的接口。由于假设事务内部是一致的,因此SQLAlchemy只会(很好,不完全,但为了便于解释......)从数据库中检索给定的数据,并在每次事务时更新相关对象的状态。由于您已在同一会话事务中查询了该对象,因此SQLAlchemy将不会在该事务范围内再次从该数据库更新该对象中的数据。如果要轮询数据库,则每次都需要使用新的事务进行轮询。

答案 1 :(得分:2)

session.refresh()对我来说也不起作用。即使我看到一个低级SELECT,刷新后对象也没有更新。

这个答案https://stackoverflow.com/a/11121788/562267提示做一个实际的提交/回滚来重置会话,这对我有用:

backgroung-image:url('...');

答案 2 :(得分:1)

您是否按照官方文档中所述尝试“过期”:

http://docs.sqlalchemy.org/en/rel_0_8/orm/session.html#refreshing-expiring

# expire objects obj1, obj2, attributes will be reloaded
# on the next access:
session.expire(user_1)
session.refresh(user_1)

对对象使用expire会导致下次访问时重新加载。

答案 3 :(得分:0)

合并会话。

u = session.query(User).get(id)
u.name = 'user1_changed'
u = session.merge(u)

这将更新数据库并返回更新的对象。