From 3f7a0ab8df9f1411a9f1ac0e152583bc7bf0c365 Mon Sep 17 00:00:00 2001 From: RamonWill Date: Wed, 2 Sep 2020 23:04:06 +0100 Subject: [PATCH] Support for multiple hosts in PostgreSQL connection string --- doc/build/changelog/unreleased_13/4392.rst | 7 +++++++ lib/sqlalchemy/engine/url.py | 7 +++++++ test/dialect/postgresql/test_dialect.py | 19 +++++++++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 doc/build/changelog/unreleased_13/4392.rst diff --git a/doc/build/changelog/unreleased_13/4392.rst b/doc/build/changelog/unreleased_13/4392.rst new file mode 100644 index 0000000000..ecb10ca25d --- /dev/null +++ b/doc/build/changelog/unreleased_13/4392.rst @@ -0,0 +1,7 @@ +.. change:: + :tags: engine, postgresql, usecase + :tickets: 4392 + + A :class:`.URL` connection now supports multiple hosts for PostgreSQL. Any + query that contains multiple hosts will now group the hosts as a string + instead of a tuple of strings. Pull request courtesy Ramon Williams. diff --git a/lib/sqlalchemy/engine/url.py b/lib/sqlalchemy/engine/url.py index 6d2f4aa244..763af74fd3 100644 --- a/lib/sqlalchemy/engine/url.py +++ b/lib/sqlalchemy/engine/url.py @@ -755,6 +755,13 @@ def _parse_rfc1738_args(name): query = None components["query"] = query + if components["query"]: + if "host" in components["query"]: + if not isinstance(components["query"]["host"], str): + components["query"]["host"] = ",".join( + components["query"]["host"] + ) + if components["username"] is not None: components["username"] = _rfc_1738_unquote(components["username"]) diff --git a/test/dialect/postgresql/test_dialect.py b/test/dialect/postgresql/test_dialect.py index 6eaa3295b9..140e19b17a 100644 --- a/test/dialect/postgresql/test_dialect.py +++ b/test/dialect/postgresql/test_dialect.py @@ -158,6 +158,25 @@ class DialectTest(fixtures.TestBase): eq_(cargs, []) eq_(cparams, {"host": "somehost", "any_random_thing": "yes"}) + def test_psycopg2_nonempty_connection_string_w_query_two(self): + dialect = psycopg2_dialect.dialect() + url_string = "postgresql://USER:PASS@/DB?host=hostA" + u = url.make_url(url_string) + cargs, cparams = dialect.create_connect_args(u) + eq_(cargs, []) + eq_(cparams["host"], "hostA") + + def test_psycopg2_nonempty_connection_string_w_query_three(self): + dialect = psycopg2_dialect.dialect() + url_string = ( + "postgresql://USER:PASS@/DB" + "?host=hostA:portA&host=hostB&host=hostC" + ) + u = url.make_url(url_string) + cargs, cparams = dialect.create_connect_args(u) + eq_(cargs, []) + eq_(cparams["host"], "hostA:portA,hostB,hostC") + class ExecuteManyMode(object): __only_on__ = "postgresql+psycopg2" -- 2.47.3