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 -~----------~----~----~----~------~----~------~--~---