diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2018-02-13 15:11:53 -0500 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2018-02-13 15:28:11 -0500 |
| commit | 15ea75981305fdad8286f6803671b864ccda13f2 (patch) | |
| tree | 5fab8588f504e023c4f7dc3944d04ba21b7b2f78 /lib/sqlalchemy/engine | |
| parent | 030915208bc843ac48a216331f315eb3c5b8b3ad (diff) | |
| download | sqlalchemy-15ea75981305fdad8286f6803671b864ccda13f2.tar.gz | |
Allow multiple plugin names
The :class:`.URL` object now allows query keys to be specified multiple
times where their values will be joined into a list. This is to support
the plugins feature documented at :class:`.CreateEnginePlugin` which
documents that "plugin" can be passed multiple times. Additionally, the
plugin names can be passed to :func:`.create_engine` outside of the URL
using the new :paramref:`.create_engine.plugins` parameter.
Change-Id: Ifc48ad120bd6c6204eda567492caf79832aeeaa5
Fixes: #4170
Diffstat (limited to 'lib/sqlalchemy/engine')
| -rw-r--r-- | lib/sqlalchemy/engine/__init__.py | 5 | ||||
| -rw-r--r-- | lib/sqlalchemy/engine/interfaces.py | 10 | ||||
| -rw-r--r-- | lib/sqlalchemy/engine/strategies.py | 1 | ||||
| -rw-r--r-- | lib/sqlalchemy/engine/url.py | 26 |
4 files changed, 37 insertions, 5 deletions
diff --git a/lib/sqlalchemy/engine/__init__.py b/lib/sqlalchemy/engine/__init__.py index 7ecc46a92..841dc405e 100644 --- a/lib/sqlalchemy/engine/__init__.py +++ b/lib/sqlalchemy/engine/__init__.py @@ -398,6 +398,11 @@ def create_engine(*args, **kwargs): up on getting a connection from the pool. This is only used with :class:`~sqlalchemy.pool.QueuePool`. + :param plugins: string list of plugin names to load. See + :class:`.CreateEnginePlugin` for background. + + .. versionadded:: 1.2.3 + :param strategy='plain': selects alternate engine implementations. Currently available are: diff --git a/lib/sqlalchemy/engine/interfaces.py b/lib/sqlalchemy/engine/interfaces.py index b9efce92e..9c3b24e9a 100644 --- a/lib/sqlalchemy/engine/interfaces.py +++ b/lib/sqlalchemy/engine/interfaces.py @@ -844,6 +844,16 @@ class CreateEnginePlugin(object): engine = create_engine( "mysql+pymysql://scott:tiger@localhost/test?plugin=myplugin") + Alternatively, the :paramref:`.create_engine.plugins" argument may be + passed as a list to :func:`.create_engine`:: + + engine = create_engine( + "mysql+pymysql://scott:tiger@localhost/test", + plugins=["myplugin"]) + + .. versionadded:: 1.2.3 plugin names can also be specified + to :func:`.create_engine` as a list + The ``plugin`` argument supports multiple instances, so that a URL may specify multiple plugins; they are loaded in the order stated in the URL:: diff --git a/lib/sqlalchemy/engine/strategies.py b/lib/sqlalchemy/engine/strategies.py index aff1dd360..4b6ee77fd 100644 --- a/lib/sqlalchemy/engine/strategies.py +++ b/lib/sqlalchemy/engine/strategies.py @@ -52,6 +52,7 @@ class DefaultEngineStrategy(EngineStrategy): plugins = u._instantiate_plugins(kwargs) u.query.pop('plugin', None) + kwargs.pop('plugins', None) entrypoint = u._get_entrypoint() dialect_cls = entrypoint.get_dialect_cls(u) diff --git a/lib/sqlalchemy/engine/url.py b/lib/sqlalchemy/engine/url.py index 483d40703..1662efe20 100644 --- a/lib/sqlalchemy/engine/url.py +++ b/lib/sqlalchemy/engine/url.py @@ -83,7 +83,12 @@ class URL(object): if self.query: keys = list(self.query) keys.sort() - s += '?' + "&".join("%s=%s" % (k, self.query[k]) for k in keys) + s += '?' + "&".join( + "%s=%s" % ( + k, + element + ) for k in keys for element in util.to_list(self.query[k]) + ) return s def __str__(self): @@ -130,6 +135,7 @@ class URL(object): def _instantiate_plugins(self, kwargs): plugin_names = util.to_list(self.query.get('plugin', ())) + plugin_names += kwargs.get('plugins', []) return [ plugins.load(plugin_name)(self, kwargs) @@ -230,10 +236,20 @@ def _parse_rfc1738_args(name): if components['database'] is not None: tokens = components['database'].split('?', 2) components['database'] = tokens[0] - query = ( - len(tokens) > 1 and dict(util.parse_qsl(tokens[1]))) or None - if util.py2k and query is not None: - query = {k.encode('ascii'): query[k] for k in query} + + if len(tokens) > 1: + query = {} + + for key, value in util.parse_qsl(tokens[1]): + if util.py2k: + key = key.encode('ascii') + if key in query: + query[key] = util.to_list(query[key]) + query[key].append(value) + else: + query[key] = value + else: + query = None else: query = None components['query'] = query |
