On 8/9/06, Nicolas Lehuen <[EMAIL PROTECTED]> wrote:
I think MySQL has also the support for INSERT OR UPDATE requests which are quite handy when implementing do_save.
You probably mean the REPLACE statement, http://www.mysql.org/doc/refman/5.1/en/replace.html If you want something a little more like standard SQL like, you can also use something a little more pythonic which eliminates the need to do a select statement first, try: c.execute( "insert into ...." ) except MySQLdb.IntegrityError, err: if e.args[0] == 1062: # duplicate key c.execute( "update ....." ) else: raise Unfortunately the MySQLdb module doesn't seem to provide any identifiers for the magic constant numbers like 1062. Also you may want to (should) use transactions, especially for the methods which execute multiple SQL statements. This will help eliminate some of the race conditions that exist in your code. Something like the following helper methods can be useful: def __init_(self, ...): .... self.in_trans = False def start_transaction(self): """Begin a database transaction. You must later call either commit_transaction() or rollback_transaction(). """ import datetime if self.in_trans: raise RuntimeError('Attempted to start a nested transaction') self.db.autocommit(False) c = self.db.cursor() # Yes, use a private local cursor here c.execute("start transaction") self.in_trans = True c.close() def commit_transaction(self): """Commit the current database transaction. The transaction should have started with the start_transaction() method. """ if not self.in_trans: raise RuntimeError('Attempted to commit before a transaction was started') db.commit() self.in_trans = False db.autocommit(True) def rollback_transaction(self): """Roll back the current database transaction. The transaction should have started with the start_transaction() method. """ if not self.in_trans: raise RuntimeError('Attempted to rollback before a transaction was started') db.rollback() self.in_trans = False db.autocommit(True) And then in your methods that use multple SQL statements use a code pattern like: def some_complex_method(self): success = False self.start_transaction() try: try: cursor.execute(" statement 1 ") cursor.execute(" statement 2 ") cursor.execute(" statement 3 ") except: success = False raise else: success = True finally: if success: self.commit_transaction() else: self.rollback_transaction() return Supposedly in a future version of python you'll be able to collapse the nested (try: try: except: finally:) into a single try block. -- Deron Meranda