This week at the EuroPython conference,
Gustavo Niemeyer announced the release of
Storm and gave a tutorial on using it.
Storm is a new object relational
Python that was developed for use in some Canonical projects, and we've
been working on moving Launchpad over to it.
I'll discuss a few of the nice features of the package:
Loose Binding Between Database Connections and Classes
Storm has a much looser binding between database connections and the
classes used to represent records in particular tables. The standard way
of querying the database uses a store object:
for obj in store.find(SomeClass, conditions):
# do something with obj (which will be a SomeClass instance)
Some things to note about this syntax:
- The class used to represent rows in the table is passed to find(),
so it is possible to have multiple classes representing a single
table. This can be useful with large tables where you are only
interested in a few columns in some cases.
- The class used to represent the table is not bound to a particular
connection. So instances of it can come from different stores.
As well as iterating over a single table, a Storm result set can iterate
over multiple tables together. For instance, if we have a table
representing people and a table representing email addresses (where each
person can have multiple email addresses), it is possible to iterate
over them in lockstep:
for person, email in store.find((Person, Email), Person.id == Email.person):
print person.name, email.address
Automatic Flushing Before Queries
One of the gotchas when using SQLObject was the way it locally cached
updates to tables. This is a great way to reduce the number of updates
sent to the database, but could result in unexpected results when
performing subsequent SELECT queries. It was up to the programmer to
remember to flush changes before doing a query.
With Storm, the store will flush pending changes automatically before
performing the query.
Easy To Execute Raw SQL
An ORM can really help when developing a database driven application,
but sometimes plain old SQL is a better fit. Storm makes it easy to
execute raw SQL against a particular store with the store.execute()
method. This method returns an object that you can iterate over to get
the tuples from the result set. It also makes sure that any local
changes have been flushed before executing the query.
Nice Clean Code
After working with SQLObject for a while, Storm has been a breath of
fresh air. The internals are clean and nicely laid out, which makes
hacking on it very easy. It was developed using test-driven
methodology, so there is an extensive test suite that makes it easy to