The
TurboGears database component is a Python module which allows the framework to connect to some database specified in the project configuration. I'd like to explore some interesting features and implementation details of this component. No particular reason, I just find it interesting since I've built several projects using this framework. The source for this component can be found
here (I'm pointing to the 1.0.7 tag because it is the most recent stable release).
The responsibility of this component is to provide database access to the TurboGears project that is being developed. This includes providing support for both
SQLAlchemy and
SQLObject. The database TurboGears component implements a conditional declaration of various SQLAlchemy and SQLObject classes and functions depending on which one is enabled for the project. This is done by attempting to import both packages. If both the SQLAlchemy and SQLObject packages are installed and importable, all declarations are executed as illustrated below.

I'm going to focus on SQLObject TurboGears support here because the current support for SQLObject is stronger than SQLAlchemy support. There are two classes defined by the TurboGears database component that help carry out SQLObject support. These classes are
AutoConnectHub and PackageHub and are illustrated below.

Typically, in a TurboGears project, you'll have several database abstractions using SQLObject. In simple projects, these abstractions are store in
model.py. However, you may have enough abstractions to justify spanning them across several modules. Each one of these modules defines a
package hub to connect to a database. A package hub is a simple variable that states the name of the project package. Since this is a TurboGears project, it will module likely contain a configuration file which specifies a database connection string. Although, there are other ways to do this.
When TurboGears encounters a
package hub, a new
PackageHub instance is created. This instance then creates a
AutoConnectHub instance by calling the
set_hub() method. This
AutoConnectHub instance that is now a member of the
PackageHub instance is the bridge between your TurboGears project and the database connection.
However, for some reason, the
set_hub() method is not invoked in the constructor of the
PackageHub instance. It is invoked for all access methods (if needed). Perhaps there is good reasoning for this design but if it is possible, I wonder if it would make more sense to have this instance created in the constructor. If this were the case, it would eliminate the need for checking if the
AutoConnectHub instance exists for every other method of the
PackageHub instance.
One last improvement I think would make sense for this component is to classify some of the functions defined here. For example, there are several functions that are either SQLObject or SQLAlchemy specific. I think these should at least be class methods. There could be two classes here called
SODBTools and
SADBTools. The ORM-specific functions could then be moved to these classes accordingly. This is just a minor improvement I feel would have major design perks.