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
-~----------~----~----~----~------~----~------~--~---

Reply via email to