14

我有以下映射(直接来自 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'|'password'

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

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

4 回答 4

17

文档

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

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

于 2013-09-16T17:43:52.867 回答
7

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

这个答案https://stackoverflow.com/a/11121788/562267暗示要进行实际的提交/回滚以重置会话,这对我有用:

user_1 = session.query(User).filter(User.id==1).one()
user_1.name # This prints: u'user1'
# update the database from another client here
session.commit()
user_1 = session.query(User).filter(User.id==1).one()
user_1.name # Should be updated now.
于 2017-05-27T16:22:45.023 回答
2

您是否尝试过官方文档中描述的“过期”:

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 会导致下次访问时重新加载。

于 2013-09-16T15:34:38.270 回答
-1

合并会话。

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

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

于 2013-09-16T16:41:44.953 回答