yeah i dont like setup.py develop either :)....but anyway, patch is good. one thing i have to nail down though is ticket #480. the main point of that ticket is to cleanly isolate ImportErrors of actual DBAPI modules apart from the containing dialect module itself. the dialects are catching all the DBAPI-related ImportErrors though so its not necessarily blocking this patch (its just they cant report them nicely).
On Mar 26, 2007, at 1:34 PM, Monty Taylor wrote: > Michael Bayer wrote: >> i think using entry points to load in external database dialects is a >> great idea. >> >> though the current six core dialects i think i still want to load via >> __import__ though since im a big fan of running SA straight out of >> the source directory (and therefore thered be no entry points for >> those in that case). >> >> so probably a check via __import__('sqlalchemy.databases') first, >> then an entry point lookup. does that work ? > > Here is a patch that implements use of entry points to load dialects. > The largest change is actually adding a get_dialect to replace the > functionality of get_module, since entry points really want to return > classes, and we only ever use the dialect class from the returned > module > anyway... > > This does not break code that I have that loads the mysql dialect, and > it does work with my new code that adds a new dialect - although I > suppose it's possible it could have broken something I didn't find. > > As a side note, I agree with Gaetan - you can run entry points and > stuff > out of the current directory, especially if you use setup.py > develop ... > but this code does the entry points second, after a check for the > module > the old way. > > Monty > > > > > === modified file 'lib/sqlalchemy/engine/strategies.py' > --- lib/sqlalchemy/engine/strategies.py 2007-02-25 22:44:52 +0000 > +++ lib/sqlalchemy/engine/strategies.py 2007-03-26 17:03:13 +0000 > @@ -42,16 +42,16 @@ > u = url.make_url(name_or_url) > > # get module from sqlalchemy.databases > - module = u.get_module() > + dialect_cls = u.get_dialect() > > dialect_args = {} > # consume dialect arguments from kwargs > - for k in util.get_cls_kwargs(module.dialect): > + for k in util.get_cls_kwargs(dialect_cls): > if k in kwargs: > dialect_args[k] = kwargs.pop(k) > > # create dialect > - dialect = module.dialect(**dialect_args) > + dialect = dialect_cls(**dialect_args) > > # assemble connection arguments > (cargs, cparams) = dialect.create_connect_args(u) > @@ -71,7 +71,7 @@ > raise exceptions.DBAPIError("Connection > failed", e) > creator = kwargs.pop('creator', connect) > > - poolclass = kwargs.pop('poolclass', getattr(module, > 'poolclass', poollib.QueuePool)) > + poolclass = kwargs.pop('poolclass', getattr > (dialect_cls, 'poolclass', poollib.QueuePool)) > pool_args = {} > # consume pool arguments from kwargs, translating a > few of the arguments > for k in util.get_cls_kwargs(poolclass): > > === modified file 'lib/sqlalchemy/engine/url.py' > --- lib/sqlalchemy/engine/url.py 2007-03-18 22:35:19 +0000 > +++ lib/sqlalchemy/engine/url.py 2007-03-26 16:47:01 +0000 > @@ -2,6 +2,7 @@ > import cgi > import sys > import urllib > +import pkg_resources > from sqlalchemy import exceptions > > """Provide the URL object as well as the make_url parsing > function.""" > @@ -69,6 +70,23 @@ > s += '?' + "&".join(["%s=%s" % (k, self.query[k]) for > k in keys]) > return s > > + def get_dialect(self): > + """Return the SQLAlchemy database dialect class > corresponding to this URL's driver name.""" > + dialect=None > + try: > + module=getattr(__import__('sqlalchemy.databases.%s' % > self.drivername).databases, self.drivername) > + dialect=module.dialect > + except ImportError: > + if sys.exc_info()[2].tb_next is None: > + for res in pkg_resources.iter_entry_points > ('sqlalchemy.databases'): > + if res.name==self.drivername: > + dialect=res.load() > + else: > + raise > + if dialect is not None: > + return dialect > + raise exceptions.ArgumentError('unknown database %r' % > self.drivername) > + > def get_module(self): > """Return the SQLAlchemy database module corresponding to > this URL's driver name.""" > try: > > === modified file 'setup.py' > --- setup.py 2007-03-23 21:33:24 +0000 > +++ setup.py 2007-03-26 17:01:51 +0000 > @@ -10,6 +10,10 @@ > url = "http://www.sqlalchemy.org", > packages = find_packages('lib'), > package_dir = {'':'lib'}, > + entry_points = { > + 'sqlalchemy.databases': [ > + '%s = sqlalchemy.databases.%s:dialect' % (f,f) for f in > + ['sqlite', 'postgres', 'mysql', 'oracle', 'mssql', > 'firebird']]}, > license = "MIT License", > long_description = """\ > SQLAlchemy is: > --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalchemy@googlegroups.com To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/sqlalchemy?hl=en -~----------~----~----~----~------~----~------~--~---