send me a reproducing test case, or at least let me see your  
mappings.  in particular, dont mix a mapping on a table that is also  
used as "secondary" in a many-to-many relationship.

On Apr 17, 2007, at 5:47 PM, chris e wrote:

>
> I'm not sure why. But when I do a delete/sql alchemy seems to be
> running the save/delete operation twice. Could this be related to a
> circular dependency in UOW that is undetected?? When deleting this is
> causing the following error because the database delete is done twice:
>
> sqlalchemy.exceptions.ConcurrentModificationError: Updated rowcount 0
> does not match number of objects updated
>
>
> To fix this I added the following, but it is a serious hack, and
> probably needs to be addressed in the unit of work code, but I'm not
> sure where to look. Code below.  I am on 0.3.5, however I tested
> against 0.3.6 as well and this bug appears to be present there as
> well.
>
>
> in orm.unitofwork.UnitOfWork
>
>     def _remove_deleted(self, obj):
>         if hasattr(obj, "_instance_key"):
>
>             # ADDED
>             # ignore key errors if the item has already been
> deleted
>             try :
>                 del self.identity_map[obj._instance_key]
>             except KeyError:
>                 pass
>         try:
>             self.deleted.remove(obj)
>         except KeyError:
>             pass
>         try:
>             self.new.remove(obj)
>         except KeyError:
>             pass
>
>
>
> in orm.mapper.Mapper
>
>
>    def delete_obj(self, objects, uowtransaction):
>         """issue DELETE statements for a list of objects.
>
>         this is called within the context of a UOWTransaction during a
> flush operation."""
>
>         if self.__should_log_debug:
>             self.__log_debug("delete_obj() start")
>
>         connection = uowtransaction.transaction.connection(self)
>
>         [self.extension.before_delete(self, connection, obj) for obj
> in objects]
>         deleted_objects = util.Set()
>         for table in self.tables.sort(reverse=True):
>             if not self._has_pks(table):
>                 continue
>             delete = []
>             for obj in objects:
>
>                 # ADDED
>                 # 4/17/07
>                 # this prevents items from being deleted twice
>                 if hasattr(obj, '_has_been_deleted_') :
>                     continue
>
>                 params = {}
>                 if not hasattr(obj, "_instance_key"):
>                     continue
>                 else:
>                     delete.append(params)
>                 for col in self.pks_by_table[table]:
>                     params[col.key] = self.get_attr_by_column(obj,
> col)
>                 if self.version_id_col is not None:
>                     params[self.version_id_col.key] =
> self.get_attr_by_column(obj, self.version_id_col)
>                 deleted_objects.add(obj)
>             if len(delete):
>                 def comparator(a, b):
>                     for col in self.pks_by_table[table]:
>                         x = cmp(a[col.key],b[col.key])
>                         if x != 0:
>                             return x
>                     return 0
>                 delete.sort(comparator)
>                 clause = sql.and_()
>                 for col in self.pks_by_table[table]:
>                     clause.clauses.append(col ==
> sql.bindparam(col.key, type=col.type))
>                 if self.version_id_col is not None:
>                     clause.clauses.append(self.version_id_col ==
> sql.bindparam(self.version_id_col.key, type=self.version_id_col.type))
>                 statement = table.delete(clause)
>                 c = connection.execute(statement, delete)
>                 if c.supports_sane_rowcount() and c.rowcount !=
> len(delete):
>                     raise
> exceptions.ConcurrentModificationError("Updated rowcount %d does not
> match number of objects updated %d" % (c.cursor.rowcount,
> len(delete)))
>
>         # ADDED
>         # this prevents items from being deleted twice
>         for obj in deleted_objects :
>             obj._has_been_deleted_ = True
>         [self.extension.after_delete(self, connection, obj) for obj in
> deleted_objects]
>
>
> >


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to