Here:

https://gist.github.com/1363860

This simple test case works just fine, meaning the problem is somewhere in my application. As you can see from the code, I tried both a "standalone" test and through Pyramid WSGI chain checking if pyramid_tm middleware possibly borks something somewhere, but both cases worked fine.

However, I can't really replicate a test scenario fully because the problematic part of my application involves several models with relationships, multiple updates. If I use EXACTLY the same flow for the savepoint, ie:

sp = transaction.savepoint()
try:
    ... # Try insert
    transaction.commit()
except IntegrityError:
    transaction.abort()
    ... # Try Update

Then the result is:



2011-11-14 12:58:29,689 INFO [sqlalchemy.engine.base.Engine][worker 0] BEGIN (implicit)

... SELECTs and UPDATEs

2011-11-14 12:58:29,726 INFO [sqlalchemy.engine.base.Engine][worker 0] SAVEPOINT sa_savepoint_1
2011-11-14 12:58:29,726 INFO  [sqlalchemy.engine.base.Engine][worker 0] {}
2011-11-14 12:58:29,727 INFO [sqlalchemy.engine.base.Engine][worker 0] INSERT INTO user_stats (user_id, tstamp, portal, ads_new, ads_modified, ads_deleted) VALUES (%(user_id)s, %(tstamp)s, %(portal)s, %(ads_new)s, %(ads_modified)s, %(ads_deleted)s) 2011-11-14 12:58:29,727 INFO [sqlalchemy.engine.base.Engine][worker 0] {'user_id': 1, 'ads_new': 0, 'ads_deleted': 0, 'tstamp': datetime.date(2011, 11, 14), 'ads_modified': 0, 'portal': 'test'} 2011-11-14 12:58:29,728 INFO [sqlalchemy.engine.base.Engine][worker 0] ROLLBACK TO SAVEPOINT sa_savepoint_1
2011-11-14 12:58:29,728 INFO  [sqlalchemy.engine.base.Engine][worker 0] {}
2011-11-14 12:58:29,754 INFO [sqlalchemy.engine.base.Engine][worker 0] BEGIN (implicit) 2011-11-14 12:58:29,756 INFO [sqlalchemy.engine.base.Engine][worker 0] UPDATE user_stats SET ads_new=(user_stats.ads_new + %(ads_new_1)s), ads_modified=(user_stats.ads_modified + %(ads_modified_1)s), ads_deleted=(user_stats.ads_deleted + %(ads_deleted_1)s) WHERE user_stats.user_id = %(user_id_1)s AND user_stats.portal = %(portal_1)s AND user_stats.tstamp = %(tstamp_1)s 2011-11-14 12:58:29,756 INFO [sqlalchemy.engine.base.Engine][worker 0] {'ads_deleted_1': 0, 'portal_1': 'test', 'ads_new_1': 0, 'tstamp_1': datetime.date(2011, 11, 14), 'user_id_1': 1, 'ads_modified_1': 1} 2011-11-14 12:58:29,956 ERROR [pyramid_debugtoolbar][worker 0] Exception at http://localhost:6543/ads/view/28328?category=
...
DetachedInstanceError: Parent instance <AdLand at 0x7ffb900faa90> is not bound to a Session; lazy load operation of attribute 'ad_base' cannot proceed




The exception being thrown when I, after the savepoint fail, try to READ a value from a model read/updated within the outer transaction. The process:

0. enter view
1. session = DBSession()
2. load some models
3. change them with POSTed data (including adding/removing/updating models through relationship class members) 4. session.flush() changes (possibly redundant because savepoint unconditionally flushes) 5. make savepoint, try insert or update some statistical models (which are not used or in any way related with those from the outer transaction), commit or abort the savepoint 6. read some data from models loaded in step 2 (reading again here because flush() in step 4 returns new IDs etc... so another phase of update* is required)
7. session.flush() everything again
8. exit view

*update involving external resources like processing related uploaded files which names depend on IDs and other data obtained after flush in step 4


The DetachedInstanceError is thrown at step 6, more precisely:




if not ad.ad_base.main_image_id and len(ad.ad_base.images):
    ...




where ad is a "main" model, ad.ad_base is a relationship() with parent (of another class), main_image_id is integer and ad.ad_base.images is a relationship to yet another model. The DetachedInstance means the 'ad' being detached, so ad.ad_base is void.


So somehow the transaction of the savepoint messes up with the external session, even though there is no relationship between those and the models inserted/updated within the inner transaction. No foreignkey or relationship() connection.




.oO V Oo.


On 11/14/2011 12:04 PM, Vlad K. wrote:

Sure, I'll whip something up.


Thanks.


.oO V Oo.


On 11/14/2011 06:01 AM, Chris McDonough wrote:
I hate to ask, but would it be possible to concoct a short Python script
that creates a SQLA DBSession (with the ZopeTransactionExtension
enabled) that issues transaction.commit/savepoint/abort commands that
demonstrates the problem being encountered?  I'd be guessing if I tried
to help with this without that.

- C




--
You received this message because you are subscribed to the Google Groups 
"pylons-discuss" 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/pylons-discuss?hl=en.

Reply via email to