summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/engine
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2018-02-13 15:11:53 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2018-02-13 15:28:11 -0500
commit15ea75981305fdad8286f6803671b864ccda13f2 (patch)
tree5fab8588f504e023c4f7dc3944d04ba21b7b2f78 /lib/sqlalchemy/engine
parent030915208bc843ac48a216331f315eb3c5b8b3ad (diff)
downloadsqlalchemy-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__.py5
-rw-r--r--lib/sqlalchemy/engine/interfaces.py10
-rw-r--r--lib/sqlalchemy/engine/strategies.py1
-rw-r--r--lib/sqlalchemy/engine/url.py26
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