On Thu, Jun 18, 2009 at 4:57 PM, Michael Bayer<mike...@zzzcomputing.com> 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 sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com
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')

Reply via email to