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" <[email protected]> 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 [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 -~----------~----~----~----~------~----~------~--~---
