Home |  MySQL Buzz |  FAQ |  Feeds |  Submit your blog feed |  Feedback |  Archive |  Aggregate feed RSS 2.0 English Deutsch Español Français Italiano 日本語 Русский
Python 2.5 released, the new ?with? statement will be great for database use
+0 Vote Up -0 Vote Down

The final release of python 2.5 is out! The list of what’s new is pretty impressive, but I’m especially happy to have the new “with” statement. Ruby has block methods, or closures, which can be used for doing very clean setup/cleanup. While full-blown Anonymous block statements were rejected from Python, the new “with” statement handles the part I care about: making it easier to write code that works correctly in the case of failures.

The 3 typical use cases are a file that needs to be closed, a lock that needs to be released, and and a database transaction that needs to be either committed or rolled back. The database case is the most interesting, since you need to handle success and failure differently, and before version 2.5 python would not allow you to have try/except/finally. You had to pick either try/except or try/finally. Python 2.5 also provides a unified try/except/finally, but the “with” statement is easier to write, and easier to read.

I’ve borrowed an example of what user code would look like for a database connection using the new “with” statement from the python docs. The idea is that the block of code should run, and then the transaction should either be committed or rolled back depending on whether the block exited normally or with an exception:

db_connection = DatabaseConnection()
with db_connection as cursor:
  cursor.execute('insert into ...')
  cursor.execute('delete from ...')
  # ... more operations ...

In order for this to work, it looks like the classes that you are working with need to properly support a context manager which defines what should happen for success and error. But, not all classes will need to implement a full blown context manager, the contextlib module allows for an easy way to add support to existing objects without the need to write a new class.

from contextlib import contextmanager

@contextmanager
def db_transaction (connection):
  cursor = connection.cursor()
  try:
    yield cursor
  except:
    connection.rollback()
    raise
  else:
    connection.commit()

db = DatabaseConnection()
with db_transaction(db) as cursor:
  ...

This was one area where Ruby code was much cleaner than Python, so it’s great to see the new functionality. It’s pretty hard for me to write code which doesn’t touch a file, a database, or threads, so it will be used a lot.

Votes:

You must be logged in with a MySQL account to vote on Planet MySQL entries. More information on PlanetMySQL voting.

Planet MySQL © 1995-2008 MySQL AB, 2008-2010 Sun Microsystems, Inc.,
2010, Oracle Corporation and/or its affiliates.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.