UPDATE: If I inject a session.expunge_all() before I query the DB for
the objects again, the "undeclared" attribute is no longer present
(i.e. I get the AttributeError I expect).

On Oct 14, 7:08 pm, mviamari <mviam...@gmail.com> wrote:
> 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