Options, ConfigParser, modules, and SQLObject connections

Discussion in 'Python' started by Robin Munn, Oct 12, 2004.

  1. Robin Munn

    Robin Munn Guest

    I've been loving SQLObject. The ability to set up a database
    connection and then completely *forget* about it and just manipulate
    Python objects has been great. But I'm running into a problem, and I'd
    like some advice.

    I'm writing an app using SQLite as the database backend, and
    interfacing to it via SQLObject. I have all my SQL table definitions
    (classes inheriting from SQLObject) in one module, and for
    simplicity's sake I'm using a module-level __connection__ variable
    that all my classes will pick up. But the SQL manual warns, "The
    __connection__ magic variable can be a little fragile -- it has to be
    defined before the class is defined. This means it must be assigned
    above the class ...: line." No problem, my module looks like this:

    --- BEGIN sqldefs.py ---

    import sqlobject

    __connection__ = sqlobject.SQLiteConnection('userdata.db')

    class Person(sqlobject.SQLObject):
    firstName = sqlobject.StringCol()
    # etc.

    ---- END sqldefs.py ----

    But I don't want to hardcode the database filename. I want to let the
    user choose the filename, and I'll be saving their choice in a
    configuration file readable by ConfigParser. Thus:

    --- BEGIN main.py ---

    import ConfigParser

    config = ConfigParser.SafeConfigParser()
    config.read('~/.myapp/myapp.cfg')
    database_filename = config.get("database", "filename")
    # etc.

    ---- END main.py ----

    And now the problem arises: how do I get that value into the
    sqldefs.__connection__ object? Once I import sqldefs, it's too late:
    __connection__ will get set at import time, and the classes will be
    created at import time.

    I've thought of a couple solutions, but neither one seems all that
    clean to me.

    1) Make sqldefs.py my main module, the one that imports all the
    others. Ew.

    2) Keep the "config" object in its own module, and make sure that the
    object has been initialized before importing sqldefs:

    --- BEGIN globalconfig.py ---
    import ConfigParser
    config = ConfigParser.SafeConfigParser()
    def load_config(filename):
    config.read(filename)
    ---- END globalconfig.py ----

    --- BEGIN main.py ---
    import globalconfig
    globalconfig.load_config('~/.myapp/myapp.cfg')
    import sqldefs
    # etc.
    ---- END main.py ----

    --- BEGIN sqldefs.py ---
    import globalconfig
    import sqlobject
    db_filename = globalconfig.config.get("database", "filename")
    __connection__ = sqlobject.SQLiteConnection(db_filename)

    class Person(sqlobject.SQLObject):
    firstName = sqlobject.StringCol()
    # etc.
    ---- END sqldefs.py ----

    This works, but it feels a little fragile to me. Suddenly the order in
    which I import my modules matters a lot. If I ever forget and import
    sqldefs before I've called load_config(), I'll get a
    ConfigParser.NoSectionError: "No section: 'database'", which may not
    be the clearest way to remind me "Hey, you imported your modules in
    the wrong order."

    I'm sure others have faced similar problems before. How have you
    managed?
     
    Robin Munn, Oct 12, 2004
    #1
    1. Advertising

  2. Robin Munn wrote:

    > I'm sure others have faced similar problems before. How have you
    > managed?


    What I do in a similar situation is to set an environment
    variable. This environment variable points to
    the .ini configuration file.

    Then I put the configuration loading in the body of
    the module. That way when it gets imported for the
    first time it executes the instructions.

    --- globalconf.py ---
    # put whatever code you need here to
    # fetch the environment variable and process the file
    db_filename = 'database_name'

    --- sqldefs.py ---
    import globalconf
    import sqlobject
    __connection__ = sqlobject.SQLiteConnection(globalconf.db_filename)

    Istvan.
     
    Istvan Albert, Oct 12, 2004
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Matthew Wilson
    Replies:
    1
    Views:
    875
    Jarek Zgoda
    Nov 23, 2003
  2. S.Ramaswamy
    Replies:
    3
    Views:
    516
    Miki Tebeka
    Jan 19, 2004
  3. Josh Close
    Replies:
    3
    Views:
    415
    Josh Close
    Aug 16, 2004
  4. Replies:
    3
    Views:
    435
  5. Jonathan Fine
    Replies:
    0
    Views:
    426
    Jonathan Fine
    Nov 17, 2009
Loading...

Share This Page