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.cn