def insert(self, topic, content, author_id): try: table = self.mapper.local_table if not self.parent_table_name: raise NoMsgBoardFoundError, "parent table should be defined" # Lock Parent table's row before adding elements to parent's write l = metadata.engine.text("SELECT id from %s where id = :parent_id for UPDATE" % self.parent_table_name, bindparams=[bindparam('parent_id', type=types.Integer)] ) l.execute(parent_id=self.parent_id) # Execute the insert on the msg_board data table with lock held on parent t = metadata.engine.text("UPDATE %(table)s SET rgt=rgt + 2 WHERE rgt >= :insert_node_val and parent_id = :parent_id; " "UPDATE %(table)s SET lft=lft + 2 WHERE lft >= :insert_node_val and parent_id = :parent_id; " "INSERT INTO %(table)s (parent_id, topic, content, depth, author_id, rank, lft, rgt, created, updated) " "values(:parent_id, :topic, :content, :depth, :author_id, " ":rank, :insert_node_val, :insert_node_val + 1, NOW(), NOW()); " % {'table': table.name}, bindparams=[bindparam('insert_node_val', type=types.Integer), bindparam('parent_id', type=types.Integer), bindparam('depth', type=types.Integer), bindparam('topic', type=types.String), bindparam('content', type=types.String), bindparam('rank', type=types.Integer), bindparam('author_id', type=types.Integer) ] ) t.execute(table_name=table.name, depth=self.depth+1, insert_node_val=self.rgt, parent_id=self.parent_id, topic=topic, rank=self.rank, content=content, author_id=author_id) self.rgt += 2 self.clear() except Exception, msg: print "Exception while inserting into msgboard: ", msg pass