Michael Bayer wrote:
> dialects can be used on their own without the engine being present  
> (such as, to generate SQL), also you can construct an engine passing  
> in your own module object which might have been procured from  
> somewhere else (or could be a mock object,for example).

Ok, yes indeed. Those are good reasons. :)


> On Mar 26, 2007, at 11:45 PM, Monty Taylor wrote:
> 
>> Always one in every bunch. :)
>>
>> I hear what you're saying about the import errors. But does it really
>> help to allow work to get done before throwing the error? I would  
>> think
>> you'd want to know right up front if you don't have a driver loaded
>> rather then letting a program actually get started up and think you  
>> can
>> write data (think fat client app) only to get a connection exception.
>>
>> But I, of course, could be very wrong about this. I am about many  
>> things...
>>
>> Monty
>>
>> Michael Bayer wrote:
>>> 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