Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sqlalchemy session.refresh does not refresh object

I have the following mapping (straight from SA examples):

class User(Base):
    __tablename__ = 'users'

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

I'm working with a MySql DB and the table has an innoDB engine.

I have a single record in my table: 1|'user1'|'user1 test'|'password'

I've opened a session with the following code:

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'

Now, when I change the record's name in the DB to 'user1_change' and commit it and then refresh the object like this:

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

It still prints: u'user1' and not u'user1_change'.

What am I missing (or setting up wrong) here?

Thanks!

like image 652
wilfo Avatar asked Sep 16 '13 14:09

wilfo


People also ask

What does session refresh do SQLAlchemy?

You can use session. refresh() to immediately get an up-to-date version of the object, even if the session already queried the object earlier.

What is session flush in SQLAlchemy?

session. flush() communicates a series of operations to the database (insert, update, delete). The database maintains them as pending operations in a transaction.

What is Sessionmaker in SQLAlchemy?

However, to standardize how sessions are configured and acquired, the sessionmaker class is normally used to create a top-level Session configuration which can then be used throughout an application without the need to repeat the configurational arguments.

What is _sa_instance_state in SQLAlchemy?

_sa_instance_state is a non-database-persisted value used by SQLAlchemy internally (it refers to the InstanceState for the instance. While not directly relevant to this section, if we want to get at it, we should use the inspect() function to access it).


1 Answers

From the docs:

Note that a highly isolated transaction will return the same values as were previously read in that same transaction, regardless of changes in database state outside of that transaction

SQLAlchemy uses a transactional unit of work model, wherein each transaction is assumed to be internally consistent. A session is an interface on top of a transaction. Since a transaction is assumed to be internally consistent, SQLAlchemy will only (well, not quite, but for ease of explanation...) retrieve a given piece of data from the database and update the state of the associated objects once per transaction. Since you already queried for the object in the same session transaction, SQLAlchemy will not update the data in that object from the database again within that transaction scope. If you want to poll the database, you'll need to do it with a fresh transaction each time.

like image 90
Silas Ray Avatar answered Oct 02 '22 19:10

Silas Ray