On Thu, Jun 18, 2009 at 4:57 PM, Michael Bayer<[email protected]> wrote:
> you can get most of this stuff from the session without any flush
> occurring. at the object level are the "new", "dirty", and "deleted"
> collections on Session. At the attribute level the
> attributes.get_history() method will illustrate the full changes made
> since the last flush on an individual object attribute. get_history()
> should be in the API docs.
Thank you! get_history is just what I needed. However, I spent a
long time being confused by something that I think is a very obscure
bug.
If you make an update to a table that has a relation to a view, then
get_history on an attribute in the view, then the history is
"forgotten". I'm attaching a file that duplicates it completely, but
here's the gist of it (after setting up as described in the docs' ORM
tutorial):
>>> ed = session.query(User).first()
>>> print sqlalchemy.orm.attributes.get_history(ed, 'fullname')
((), [u'Ed Jones'], ())
>>> ed.fullname = 'Eduardo Jones'
>>> print sqlalchemy.orm.attributes.get_history(ed, 'fullname')
(['Eduardo Jones'], (), [u'Ed Jones'])
>>> # so far so good
>>> print sqlalchemy.orm.attributes.get_history(ed.userview, 'name')
((), [u'ed'], ())
>>> print sqlalchemy.orm.attributes.get_history(ed, 'fullname')
((), ['Eduardo Jones'], ())
... now get_history thinks fullname has always been Eduardo Jones.
Is this a bug I should file, or something I should have expected?
Thanks as always!
--
- Catherine
http://catherinedevlin.blogspot.com/
*** PyOhio * July 25-26, 2009 * pyohio.org ***
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---
from sqlalchemy import create_engine
engine = create_engine('sqlite:///:memory:', echo=False)
from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
metadata = MetaData()
users_table = Table('users', metadata,
Column('id', Integer, primary_key=True),
Column('name', String(12)),
Column('fullname', String(40)),
Column('password', String(40))
)
metadata.create_all(engine)
class User(object):
def __init__(self, name, fullname, password):
self.name = name
self.fullname = fullname
self.password = password
def __repr__(self):
return "<User('%s','%s', '%s')>" % (self.name, self.fullname, self.password)
from sqlalchemy.orm import mapper, relation, backref
mapper(User, users_table)
ed_user = User('ed', 'Ed Jones', 'edspassword')
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)
session = Session()
session.add(ed_user)
session.commit()
#########################################################################################################
# everything up to here comes from the ORM tutorial at http://www.sqlalchemy.org/docs/05/ormtutorial.html
engine.connect().execute('CREATE VIEW userview AS SELECT id, name FROM users')
class UserView(object):
pass
userview = Table('userview', metadata,
Column('id', ForeignKey('users.id'), primary_key=True),
autoload=True, autoload_with=engine)
mapper(UserView, userview,
properties={'user': relation(User, uselist=False, lazy=True,
backref=backref('userview', uselist=False))})
import sqlalchemy.orm.attributes
ed = session.query(User).first()
print sqlalchemy.orm.attributes.get_history(ed, 'fullname')
ed.fullname = 'Eduardo Jones'
print sqlalchemy.orm.attributes.get_history(ed, 'fullname')
print sqlalchemy.orm.attributes.get_history(ed.userview, 'name')
print sqlalchemy.orm.attributes.get_history(ed, 'fullname')