Skip to content
This repository was archived by the owner on Aug 19, 2025. It is now read-only.

Commit ae55f0c

Browse files
Merge pull request #42 from encode/fix-database-url-with-empty-netloc
Fix database URLs when netloc is empty
2 parents 76b04c2 + d3de630 commit ae55f0c

File tree

2 files changed

+20
-0
lines changed

2 files changed

+20
-0
lines changed

databases/core.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,11 @@ async def rollback(self) -> None:
246246
await self._connection.__aexit__()
247247

248248

249+
class _EmptyNetloc(str):
250+
def __bool__(self) -> bool:
251+
return True
252+
253+
249254
class DatabaseURL:
250255
def __init__(self, url: typing.Union[str, "DatabaseURL"]):
251256
self._url = str(url)
@@ -282,6 +287,10 @@ def hostname(self) -> typing.Optional[str]:
282287
def port(self) -> typing.Optional[int]:
283288
return self.components.port
284289

290+
@property
291+
def netloc(self) -> typing.Optional[str]:
292+
return self.components.netloc
293+
285294
@property
286295
def database(self) -> str:
287296
return self.components.path.lstrip("/")
@@ -317,6 +326,11 @@ def replace(self, **kwargs: typing.Any) -> "DatabaseURL":
317326
driver = kwargs.pop("driver", self.driver)
318327
kwargs["scheme"] = f"{dialect}+{driver}" if driver else dialect
319328

329+
if not kwargs.get("netloc", self.netloc):
330+
# Using an empty string that evaluates as True means we end
331+
# up with URLs like `sqlite:///database` instead of `sqlite:/database`
332+
kwargs["netloc"] = _EmptyNetloc()
333+
320334
components = self.components._replace(**kwargs)
321335
return self.__class__(components.geturl())
322336

tests/test_database_url.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,9 @@ def test_replace_database_url_components():
4040
new = u.replace(port=123)
4141
assert new.port == 123
4242
assert str(new) == "postgresql://localhost:123/mydatabase"
43+
44+
u = DatabaseURL("sqlite:///mydatabase")
45+
assert u.database == "mydatabase"
46+
new = u.replace(database="test_" + u.database)
47+
assert new.database == "test_mydatabase"
48+
assert str(new) == "sqlite:///test_mydatabase"

0 commit comments

Comments
 (0)