As an addendum to my previous posts, here is a run-through on my
solution for anyone who might encounter a similar problem at a future
date.

***Disclaimer: I don't think this is the best solution, but it seemed
to work for me.***

Brief background: I need to write an application that may potentially
live in the same database as another app, both running under MySQL.
Hence, it is necessary to generate tables for my TG2 project that
include a user-configurable prefix in the project .ini files.

First, I tried using metaclasses to resolve the issue of having to
tack on a __tablename__ to each object in my app's model. This didn't
work, and I found out why. In SQLAlchemy, the declarative_base()
function returns a class that itself is already generated from a
metaclass. The result is that you're left with an error message (one
that is almost comical if you imagine it spoken as a sage's riddle)
along the lines of:

metaclass conflict: the metaclass of a derived class must be a
(non-strict) subclass of the metaclasses of all its bases

Thus, I stuck with my original consideration of doing something like:

'''
class User (DeclarativeBase):
    __tablename__ = config.get("database.table.prefix") + "users"
'''

This is a little extra work since it needs to be added to each table
in the model. It isn't elegant, and when I get a little extra time
I'll see if there's something else I can do along the lines of
Gustavo's suggestions. (I still think some derivation of that would
work.)

Second, since I wanted the table prefix to be configurable from the
project .ini files, there was the issue of being unable to use
config.get() "out of the box," so to speak. Since the model module has
to be imported well before the "global_conf" is merged into it (or I
guess that's local_conf or app_conf, depending on context!), trying to
use the config object doesn't work without some project changes. I did
some introspection into TG2's configuration module and figured that if
I could tweak the module loading order (in my project) it would work.
So far, so good. Here's what I had to do:

I first set up a global module that would hold the application
configs. I could've used the Globals object, and I'll probably make
changes using it instead as this was a quick hack. As such, a simple
module along the lines of:

'''
from tg.configuration import Bunch

locals = {}
def update_locals (config):
    global locals
    locals = Bunch(config)
'''

Does nicely. Using the global statement makes me feel kind of dirty, however.

Next, under config/middleware.py, I moved these statements:

'''
from projectname.config.app_cfg import base_config
from projectname.config.environment import load_environment
make_base_app = base_config.setup_tg_wsgi_app(load_environment)
'''

Into the make_app() function. These were placed AFTER doing something like:

'''
from projectname.config.local_config import update_locals
update_locals(app_conf)
'''

Which gives the application time to examine the configs sent to it
from the environment (paster, etc) before the model is loaded.

I did something similar to websetup.py so the ``paster setup-app
[projectphase].ini`` would work, too.

So far, I've tested this with a quickstart generated TG2 project (with
authentication) using paster and mod_wsgi. It seems to work, prefixes
and all. I can't help but feel this is a blasphemous abuse of the
templates quickstart generates for us, though... So, I apologize for
both a lengthy follow-up *and* my blatant abuse of TG2's quickstart
templates. :)

Thanks, everyone, for your help!

-- 
Regards,
Benjamin

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"TurboGears" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/turbogears?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to