Mike, Thank you for for the tip on _sessions, I think it is worth publishing since it can make debugging easier. Regarding documentation it will be good to mention session close() is not like file close() and closed session is just ready for another transaction. Context manager is typically introduced with file operations, so python beginner may be left with false assumption closed session is gone and there is no need to bother with it. Separate and external session life cycle perhaps also needs another wording. SQA user must be aware what session are defined and from which session does the object come. Objects like queries have information on session internally, so "separate and external management of session life cycle" looks impossible for them. BTW are queries the only objects keeping a reference to session after close()? I've spent quite some time trying to understand why do I get already attached to session error while all operations were handled with context manager. In my application GUI I was using a query from one session to build dropdown selection and then tried to modify object attribute with dropdown selected object in another session. Code demonstrating thy blunder is attached below. Kind Regards, Jacek
>>> from sqlalchemy.orm.session import _sessions >>> from sqlalchemy import inspect as insp >>> >>> #create a session ... >>> ses=Session() >>> # it is empty of course ... >>> for i in ses: print i ... >>> # query some data ... >>> qr=ses.query(MeterReading) >>> qr.count() 43 >>> 43 43 >>> # session is still empty - no object referenced yet ... >>> for i in ses: print i ... >>> r0 = qr[0] >>> # now we have one object in ses ... >>> for i in ses: print i ... <nmeter.appdata.MeterReading object at 0x7f2b16606410> >>> # close will empty ses ... >>> ses.close() >>> for i in ses: print i ... >>> # let's take a picture before we say farewell ... >>> ses <sqlalchemy.orm.session.Session object at 0x7f2b62fec2d0> >>> insp(r0).session >>> # replace old ses with brand new from the factory ... >>> ses = Session() >>> ses.add(r0) >>> # take another object form query qr and add it to session - it will throw an exception ... >>> r1 = qr[1] >>> ses.add(r1) Traceback (most recent call last): [...] sqlalchemy.exc.InvalidRequestError: Object '<MeterReading at 0x7f2b166065d0>' is already attached to session '2' (this is '3') >>> # because old ses is still there, qr is associated with it and so is r1 ... >>> for i in _sessions.items(): print i ... (1, <sqlalchemy.orm.session.Session object at 0x7f2b4c1e5c10>) (2, <sqlalchemy.orm.session.Session object at 0x7f2b62fec2d0>) (3, <sqlalchemy.orm.session.Session object at 0x7f2b4c1e5b50>) >>> insp(r0).session <sqlalchemy.orm.session.Session object at 0x7f2b4c1e5b50> >>> insp(r1).session <sqlalchemy.orm.session.Session object at 0x7f2b62fec2d0> >>> insp(qr).session <sqlalchemy.orm.session.Session object at 0x7f2b62fec2d0> >>> >>> # what if MeterReading has an atribute meter which is a realtionship ... insp(MeterReading.meter).mapper.class_ <class 'nmeter.appdata.Meter'> >>> >>> # suppose we want to modify r0.meter ... >>> qm = insp(r1).session.query(Meter) >>> qm.count() 3 >>> # r0.meter modification with qm will fail ... >>> r0.meter = qm[1] Traceback (most recent call last): [...] sqlalchemy.exc.InvalidRequestError: Object '<Meter at 0x7f2b16622250>' is already attached to session '2' (this is '3') >>> # obviously it adds meter to r0 session, so we need to disconnect it form current session ... m1 = qm[1] >>> insp(m1).session.expunge(m1) >>> r0.meter = m1 >>> # now it works, -- SQLAlchemy - The Python SQL Toolkit and Object Relational Mapper http://www.sqlalchemy.org/ To post example code, please provide an MCVE: Minimal, Complete, and Verifiable Example. See http://stackoverflow.com/help/mcve for a full description. --- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at https://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.