Hi,
I encountered a strange situation when trying to delete an object from
a parent table with all its child
objects. I found that if you call objectstore.commit() after the
deletion of each child object, then you got problem when deleting the
parent object.
The parent table is called 'brand', which has a one-to-many
relationship with the child table 'series', which has a foreign key
'brand_id' referring to the 'brand' table. The object classes, tables
and mappers are defined as follows:
class Series(object):
pass
t_series = Table('series', _engine, autoload=True)
Series.mapper = mapper(Series, t_series)
class Brand(object):
pass
t_brands = Table('brands', _engine, autoload=True)
Brand.mapper = mapper(Brand, t_brands, properties={
'series': relation(mapper(Series, t_series),
order_by=Series.c.disp_order)
})
Now I try to delete brand with id 1 and all series referring to it:
objectstore.clear()
b = Brand.mapper.get(1)
for s in b.series:
objectstore.delete(s)
objectstore.delete(b)
objectstore.commit()
This works fine, SQLAlchemy groups all the deletion in one UOW and
produces the following output:
[2006-05-07 21:37:40,608] [engine]: DELETE FROM series WHERE
series.series_id = %(series_id)s
[2006-05-07 21:37:40,608] [engine]: [{'series_id': 5}, {'series_id':
4}, {'series_id': 6}, {'series_id': 1205}]
[2006-05-07 21:37:40,625] [engine]: DELETE FROM public.brands WHERE
brands.brand_id = %(brand_id)s
[2006-05-07 21:37:40,625] [engine]: [{'brand_id': 1}]
HOWEVER, if I decide to commit each deletion of the series immediately
and separately, the last deletion (of the brand object itself), will
fail:
objectstore.clear()
b = Brand.mapper.get(1)
for s in b.series:
objectstore.delete(s)
objectstore.commit() ## If we commit immediately
objectstore.delete(b)
objectstore.commit() ## The last deletion will fail
The debug output and trace looks like the following:
2006-05-07 21:36:10,280] [engine]: DELETE FROM series WHERE
series.series_id = %(series_id)s
[2006-05-07 21:36:10,280] [engine]: [{'series_id': 5}]
[2006-05-07 21:36:10,280] [engine]: DELETE FROM series WHERE
series.series_id = %(series_id)s
[2006-05-07 21:36:10,280] [engine]: [{'series_id': 4}]
[2006-05-07 21:36:10,280] [engine]: DELETE FROM series WHERE
series.series_id = %(series_id)s
[2006-05-07 21:36:10,280] [engine]: [{'series_id': 6}]
[2006-05-07 21:36:10,280] [engine]: DELETE FROM series WHERE
series.series_id = %(series_id)s
[2006-05-07 21:36:10,296] [engine]: [{'series_id': 1201}]
Traceback (most recent call last):
File "<input>", line 1, in ?
File "build\bdist.win32\egg\sqlalchemy\mapping\objectstore.py", line
250, in commit
File "build\bdist.win32\egg\sqlalchemy\mapping\objectstore.py", line
81, in flush
File "build\bdist.win32\egg\sqlalchemy\mapping\unitofwork.py", line
249, in flush
File "build\bdist.win32\egg\sqlalchemy\mapping\unitofwork.py", line
374, in execute
File "build\bdist.win32\egg\sqlalchemy\mapping\unitofwork.py", line
536, in execute
File "build\bdist.win32\egg\sqlalchemy\mapping\unitofwork.py", line
459, in execute
File "build\bdist.win32\egg\sqlalchemy\mapping\properties.py", line
483, in process_dependencies
File "build\bdist.win32\egg\sqlalchemy\mapping\properties.py", line
579, in _synchronize
File "build\bdist.win32\egg\sqlalchemy\mapping\sync.py", line 87,
in execute
File "build\bdist.win32\egg\sqlalchemy\mapping\sync.py", line 122,
in execute
File "build\bdist.win32\egg\sqlalchemy\mapping\mapper.py", line 497,
in _setattrbycolumn
File "build\bdist.win32\egg\sqlalchemy\mapping\properties.py", line
33, in setattr
File "build\bdist.win32\egg\sqlalchemy\attributes.py", line 55, in
__set__
File "build\bdist.win32\egg\sqlalchemy\attributes.py", line 355, in
set_attribute
File "build\bdist.win32\egg\sqlalchemy\mapping\unitofwork.py", line
65, in value_changed
File "build\bdist.win32\egg\sqlalchemy\mapping\unitofwork.py", line
182, in register_dirty
File "build\bdist.win32\egg\sqlalchemy\mapping\unitofwork.py", line
147, in _validate_obj
InvalidRequestError: Detected a mapped object not present in the
current thread's Identity Map: '(<class '__main__.Series'>, (5,),
None)'. Use objectstore.import_instance() to place deserialized
instances or instances from other threads
Why would the last deletion fail and why does the mapper demand a
series object from the identity map in this case? After deleting all
the 'series' objects and before the deletion of the parent 'brand'
object, I checked session.deleted, session.new, session.dirty and
session.modified_lists, and they all seem empty ('[]' shown on
console)
How can I find out what's wrong here? I am using SQLAlchemy 0.1.7 with
Python 2.4.2 and PostgreSQL 8.1.
--
Hong Yuan
大管家网上建材超市
装修装潢建材一站式购物
http://
www.homemaster.c------------------------------------------------------
-
Using Tomcat but need to do more? Need to support web services,
security?
Get stuff done quickly with pre-integrated technology to make your
job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache
Geronimo
http://sel.as-us.falkag.net/sel?
cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
Sqlalchemy-users mailing list
Sqlalchemy-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sqlalchemy-users
n