I've tried the new pylons.database code that has support for passing
in engine options, but it still doesn't quite get at the problem of
setting database options in the config file. (For those who get bored
with this, there are a couple other SQLAlchemy questions at the end of
this message.)
My use case is having it recognize sqlalchemy.echo_pool (boolean) and
sqlalchemy.pool_recycle (int). The latter is needed for MySQL, and
the former is useful when debugging connections.
In my application I created models/sqlalchemy_util.py containing:
===
import pylons.database
import sqlalchemy as sa
from sqlalchemy.ext.sessioncontext import SessionContext
def create_engine():
return pylons.database.create_engine(
echo_pool=asbool(CONFIG.get("sqlalchemy.echo_pool", False)),
pool_recycle=int(CONFIG.get("sqlalchemy.pool_recycle", -1)),
)
def make_session():
engine = create_engine()
return sa.create_session(bind_to=engine)
def get_session_context():
return SessionContext(make_session, scopefunc=pylons.database.app_scope)
===
This provides what I need but doesn't support keyword arguments.
One problem is that pylons.database.get_engine_args returns a tuple of
(uri, echo). This makes it impossible to expand get_engine_args to
parse additional options without also modifying create_engine and
returning an ever-longer tuple. I propose restructuring them like
this:
===
def get_engine_conf(uri=None, **kwargs):
# Handle 'uri' the same way as now.
if 'echo' not in options or kwargs['echo'] is None:
echo' = pylons.util.config_get('sqlalchemy.echo', False)
if echo != 'debug':
echo = asbool(echo)
kwargs['echo'] = echo
if 'echo_pool' not in kwargs:
kwargs['echo_pool'] =
asbool(pylons.util.config_get('sqlalchemy.echo_pool', False))
if 'pool_recycle' not in kwargs:
kwargs['pool_recycle'] =
int(pylons.util.config_get('sqlalchemy.pool_recycle', -1)) # Raises
ValueError
return uri, options
def create_engine(uri=None, **kwargs):
uri, kwargs = get_engine_conf(uri, **kwargs)
# Rest same as existing.
===
Then we can gradually add more standard options over time, and the
user can replace the function with their own enhanced version.
Although we might as well just support all 17 existing options now and
get it over with. I wish we could just pass through all
'sqlalchemy.*' options as is but we have to convert the types.
This would also make it easy to create a session context using your
new options. Otherwise you have to write your own make_session() too
because of the way SessionContext takes an engine factory as a
constructor argument.
A couple other points:
The "SQLAlchemy for People in a Hurry" cookbook article contains a mistake.
http://docs.pythonweb.org/display/pylonscookbook/SQLAlchemy+for+people+in+a+hurry
It says you can put
metadata = DynamicMetaData()
at the top of your models.__init__ and it will automatically read the
'sqlalchemy.dburi' config variable. But of course SQLAlchemy doesn't
know anything about the Pylons config file so you get an "no engine
has been connected" error when you try to use it.
I've gone to doing it this way (without the ORM):
engine = pylons.database.create_engine()
meta = BoundMetaData(engine)
table1 = Table(....)
t1c = t1.columns
Or this way (with the ORM):
engine = session_context.current.bind_to
meta = BoundMetaData(engine)
table1 = Table(...)
t1c = t1.columns
class Class1(object):
pass
mapper(Class1, table1)
Is this safe? It seems so because the engine checks out connections
from a pool, and even though the session context ostensibly creates a
new engine with each session, it's still really the same engine
anyway, even if I use t1c or Class1.c in a function that has a
different current session.
--
Mike Orr <[EMAIL PROTECTED]>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"pylons-discuss" 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/pylons-discuss?hl=en
-~----------~----~----~----~------~----~------~--~---