Repository navigation
Conversation
A URL such as postgres://u:p@host1,host2:5432/db is libpq's failover syntax. urlparse reads "host1,host2" back as one hostname, so asyncpg tried to resolve it as a single DNS name and failed. Split the host part of postgres, postgresql, asyncpg and psycopg URLs on commas, each entry with its own optional port (a bare host takes the port of the query string or 5432), and pass lists to the clients. asyncpg takes the lists as they are; psycopg gets the comma joined strings libpq expects. psycopg also reads target_session_attrs from the URL query, as asyncpg already did through its connect arguments. Single-host URLs are unchanged. Fixes tortoise#1924
Merging this PR will not alter performance1 warning
Comparing |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Accept libpq style multi-host PostgreSQL URLs,
postgres://user:pass@host1:5432,host2:5433/db?target_session_attrs=read-write, for thepostgres,postgresql,asyncpgandpsycopgschemes. The host part is split on commas, each entry takes its own optional port, and a bare host takes the port from the query string or5432. A single-host URL gives exactly the same result as before. When a URL lists several hosts, a?host=value in its query string is ignored.The clients take the lists as they are for asyncpg, and psycopg joins them with commas for libpq. psycopg also reads
target_session_attrsfrom the URL, which asyncpg already accepted through its connect arguments, so the example above works with both drivers.Motivation and Context
Fixes #1924.
urlparsereturnshost1,host2as one hostname, so asyncpg tried to resolve it as a single DNS name and failed withsocket.gaierror. psycopg already worked for a shared port (libpq splits the string itself) but not for per-host ports. The closed attempt in #2267 split hosts for asyncpg only; this also covers per-host ports, IPv6 literals, psycopg and thetarget_session_attrsparameter from the issue's own URL.How Has This Been Tested?
tests/backends/test_db_url.py(shared port, per-host ports, query parameters, IPv6, the query port as default, invalid port and empty host, other schemes unchanged) andtests/backends/test_connection_params.py(the host and port lists reach asyncpg, the joined strings reach psycopg's conninfo, single-host types staystrandint). Twelve of them fail ondevelopand all pass with the change.tests/backendson Linux against PostgreSQL 17: 93 passed, 6 skipped, 1 xfailed.host:54399,host:54320), with and without?target_session_attrs=read-write: asyncpg and psycopg both connect to the second host on Linux. On Windows, psycopg's own connection pool fails the same way with a dead first host outside Tortoise, so that case was not used there.mypy tortoise/backendsis clean andruffreports nothing new on the touched files.Checklist: