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.

Reply via email to