Michael,

First, Thanks for your help.
Second, something still isn't right.  Here's the code in question:

        obj = Obj()
        org = Org()
        self.assertNotEqual(obj, None)
        self.assertNotEqual(org, None)

        #Nonsense_var is not representative of a table column,
        #and is dynamically declared (i.e. not defined in the class
definition).
        obj.nonsense_var = 12
        org.nonsense_var = 11
        self.assertEqual(obj.nonsense_var, 12)
        self.assertEqual(org.nonsense_var, 11)

        org.obj = obj

        util.database.commit_session()
        objid = obj.id
        orgid = org.id

        util.database.get_session().expire(obj)
        util.database.get_session().expire(org)

        obj = None
        org = None
        self.assertEqual(obj, None)
        self.assertEqual(org, None)

        obj = Obj.get_by(id=objid)
        org = Org.get_by(id=orgid)
        self.assertNotEqual(obj, None)
        self.assertNotEqual(org, None)

        self.assertRaises(AttributeError, getattr, obj,
'nonsense_var')
        self.assertRaises(AttributeError, getattr, org,
'nonsense_var')


I don't get the expected AttributeError at the end.  Interestingly, if
I delete the org.obj = obj declaration (which is a one-to-one
relationship) it runs as expected.

The whole point of this is to be able to determine if a given
attribute is part of the object (and corresponding table) definition.
This would be useful, for example, to detect renamed attributes,
deleted attributes, or data transformations when committed to the
database (i.e. 10/11/2009 becomes datatime(2009, 10, 11)).

Thanks

Mike

On Oct 14, 6:44 pm, Michael Bayer <mike...@zzzcomputing.com> wrote:
> On Oct 14, 2009, at 9:15 PM, mviamari wrote:
>
>
>
> > So if I read the documentation right, it appears that because I'm
> > accessing the object via the primary key, it looks the object up
> > locally (i.e. in the session) and returns that object.  Other than
> > doing a query/lookup on another attribute, how can I force it to
> > create the object from the data in the database?
>
> > The key here is that I'd like to be able to verify if an attribute
> > (that corresponds to a DB column) has been deleted.
>
> > To complicate matters, I'd also like to be able to do this in a nested
> > transaction, without destroying the session (so I can rollback
> > everything when I'm done).
>
> the Session/Query is quite flexible and individual objects can be  
> refreshed, expired, etc. as needed.    The most direct route is to  
> expire() the object in question.   Alternatively use the  
> populate_existing() method on query which forces a reload.
>
> However, if all of this is occuring within a transaction that is  
> isolated from others, none of that should be needed - the Session in  
> its default settings always synchronizes its state against the current  
> transaction automatically, and the object in your identity map does  
> represent what's in that transaction - unless you've issued an UPDATE  
> or DELETE statement using a plain SQL expression (in which case I'd  
> recommend checking out query.update() and query.delete()).   After a  
> rollback() or commit() when the transaction goes away, all the  
> contents of the session are expired so that the new state is loaded  
> into the next transaction.
>
>
>
> > Thanks,
>
> > Mike
>
> > On Oct 14, 7:00 am, "Michael Bayer" <mike...@zzzcomputing.com> wrote:
> >> mviamari wrote:
>
> >>> Hello,
>
> >>> I'm writing tests for my database, and I've run into a little bit of
> >>> confusion.
>
> >>> Say I have a class (we'll call it person) with two declared  
> >>> attributes
> >>> that correspond to db columns:
>
> >>> person.id
> >>> person.name
>
> >>> If I randomly assign a person object another attribute dynamically:
>
> >>> person.undeclared_value = 'New'
>
> >>> That value doesn't get stored in the database.  (That part I  
> >>> expected
> >>> and understand).
> >>> What I don't understand is if I commit the object, set it to None  
> >>> (to
> >>> presumably garbage collect it) and then reacquire it from the DB,
> >>> sometimes that dynamically declared attribute is still pesent:
>
> >>> person = Person()
> >>> person.name = 'John Smith'
> >>> person.new_attr = 'New'
>
> >>> commit()
> >>> id = person.id #id isn't assigned till after a commit
>
> >>> person = None
> >>> person = Person.get_by(id=id)
>
> >>> #This is expected to be true
> >>> assert person.name = 'John Smith'
>
> >>> #This is expected to yield an AttributeError, but sometimes it  
> >>> doesn't
> >>> assert person.new_attr = 'New'
>
> >>> Based on my tests, it appears that the sometimes it doesn't is
> >>> whenever there are relationships created in the session.  If I only
> >>> create one object and follow the above pattern, I get the expected
> >>> results.  If I create two objects and the relationship between them,
> >>> then I get the unexpected results.
>
> >>> Does anyone have any idea what might be going on? I think the object
> >>> is getting stored in the session, and when I reobtain the object it
> >>> just uses the reference in the session.
>
> >> this is the identity map at work.  Read "Is the session a cache?" 
> >> athttp://www.sqlalchemy.org/docs/05/session.html#frequently-asked-quest
> >> ...
> >> .
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to