wiki:UsingModelsOutsideTurboGears
Warning: Can't synchronize with repository "(default)" (Unsupported version control system "svn": No module named svn). Look in the Trac log for more information.

Version 5 (modified by stickystyle@…, 13 years ago) (diff)

0.8.9 does not have turbogears.update_config()

Sometimes you want to use classes in your data model outside your TurboGears application.

For example, you might want to write a script to:

  • Initialize your database
  • Perform scheduled maintenance tasks
  • Insert or update data based on external events, like an email responder.

If you just try to import your model.py, you may get a traceback message that ends with this error:

KeyError: 'No database configuration found!'

The problem is that you haven't told SQLObject where to find your database; this information is in your application's configuration scripts.

To use your database from outside the application, create a script that looks like this:

#!/usr/bin/env python2.4
# If you're not running on a Unix-like platform, you can omit the first "#!" line.

# Hook up SQLObject to your database configuration from either "dev.cfg" or "prod.cfg"

# This assumes that the script lives in your top-level application directory; if
# that's not the case, you will have to provide a full path to your configuration 
# and set your PYTHONPATH so that the model import succeeds.
# The value for modulename can be pulled right from start-project_name.py 
# script in the top-level application directory.
import turbogears
turbogears.update_config(configfile="dev.cfg", modulename="project_name.config")

# Note: turbogears 0.8.9 doesn't have .update_config()

# Now you can import your model. 
from myapp.model import *

# And now you have full access to your model
s = SomeClass.select()

# If you make any changes, you need to manually commit them before exiting.
turbogears.hub.commit()

Note that if you're using SQLite for your database, a long-running script outside your application can lock the database for long periods of time. To avoid this, isolate your database access from your expensive operations:

#!/usr/bin/env python2.4

# Script to periodically do expensive things.

import turbogears
turbogears.update_config(configfile="dev.cfg", modulename="project_name.config")
from myapp.model import *

def read_from_db():
    calculations = ScheduledCalculation.select(ScheduledCalculation.q.result==None)
    return [(calc.id, calc.what_to_do) for calc in calculations]

def write_to_db(results):
    for calc_id, result in results:
        calc = ScheduledCalculation.get(calc_id)
        calc.result = result


# Get the list of what to do from the database.  The result list we get should
# not include any SQLObject-derived objects.
calculations = read_from_db()

# Now we can do the expensive calculations, since there won't be any 
# live objects locking the database.
results = []
for calc_id, what_to_do in calculations:
  results.append((calc_id, do_expensive_calc(what_to_do))

# Now write them all to the database
write_to_db(results)
turbogears.hub.commit()