--- lib/sqlalchemy/engine/url.py | 14 ++++++++++---- test/dialect/mssql/test_engine.py | 3 ++- 2 files changed, 12 insertions(+), 5 deletions(-) --- a/lib/sqlalchemy/engine/url.py +++ b/lib/sqlalchemy/engine/url.py @@ -14,6 +14,7 @@ argument; alternatively, the URL is a pu be used directly and is also accepted directly by ``create_engine()``. """ +import inspect import re from .interfaces import Dialect @@ -218,7 +219,7 @@ class URL(object): return translated -def make_url(name_or_url): +def make_url(name_or_url, separator='&'): """Given a string or unicode instance, produce a new URL instance. The given string is parsed according to the RFC 1738 spec. If an @@ -226,12 +227,12 @@ def make_url(name_or_url): """ if isinstance(name_or_url, util.string_types): - return _parse_rfc1738_args(name_or_url) + return _parse_rfc1738_args(name_or_url, separator) else: return name_or_url -def _parse_rfc1738_args(name): +def _parse_rfc1738_args(name, qs_sep): pattern = re.compile( r""" (?P[\w\+]+):// @@ -261,7 +262,12 @@ def _parse_rfc1738_args(name): if len(tokens) > 1: query = {} - for key, value in util.parse_qsl(tokens[1]): + if 'separator' in inspect.signature(util.parse_qsl).parameters: + qs_dict = util.parse_qsl(tokens[1], separator=qs_sep) + else: + qs_dict = util.parse_qsl(tokens[1]) + + for key, value in qs_dict: if util.py2k: key = key.encode("ascii") if key in query: --- a/test/dialect/mssql/test_engine.py +++ b/test/dialect/mssql/test_engine.py @@ -164,7 +164,8 @@ class ParseConnectTest(fixtures.TestBase u = url.make_url( "mssql+pyodbc://@server_name/db_name?" "driver=ODBC+Driver+17+for+SQL+Server;" - "authentication=ActiveDirectoryIntegrated" + "authentication=ActiveDirectoryIntegrated", + separator=';' ) connection = dialect.create_connect_args(u) eq_(connection[1], {})