Access the database in an extension module

Sometimes I need an extension which gives me a special list or selection box, e.g. to select users grouped by roles. Such function should access the database directly; otherwise I'd need to create a list in the page template, and then hand it over to the function.

This is how I do it:

    """
    the module, put in $TRACKER_HOME/extensions...
    """
    db = None
    tracker_home = None

    def check_db()
       global db
       if db is None:
           from roundup import instance
           tracker = instance.open(tracker_home)
           db = tracker.open('admin')

    def useful_function(...):
       "no db argument required nor supported"
       check_db()
       ...

    def init(instance):
       global tracker_home
       tracker_home = instance.tracker_home
       instance.registerUtil('useful_function', useful_function)

This way the database is fetched at first use of one of the registered functions, and reused at every further call.

It doesn't work to set the db value in the init function directly, since the following causes an infinite recursion loop at tracker startup:

    def init(instance):
       "DOESN'T WORK -- DON'T USE!"
       global db
       from roundup import instance as ins_module
       tracker = ins_module.open(instance.tracker_home)
       db = tracker.open('admin')

Feedback/comments welcome.


comments:

Problems when using sqlite --wiki, Tue, 27 Mar 2007 01:40:48 +1000 reply
When a single-user database backend (e.g. SQLite?) is used, problems might occur because the database is locked when someone else tries to access it. Therefore it might be necessary to close the connection after use (untested):

def close_db() global db db.close() db = None

def useful_function(...): "no db argument required nor supported" global db check_db() try: # do the interesting stuff and, when writing, # don't forget to commit()... return interesting_data finally: close_db()

Just in case... I didn't suffer any problems myself.