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

Commit 6d3e8c8

Browse files
Add min_size, max_size, and ssl connection options
1 parent 9bee7cb commit 6d3e8c8

File tree

6 files changed

+94
-8
lines changed

6 files changed

+94
-8
lines changed

databases/backends/mysql.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,38 @@
1717

1818

1919
class MySQLBackend(DatabaseBackend):
20-
def __init__(self, database_url: DatabaseURL) -> None:
21-
self._database_url = database_url
20+
def __init__(self, database_url: typing.Union[DatabaseURL, str]) -> None:
21+
self._database_url = DatabaseURL(database_url)
2222
self._dialect = pymysql.dialect(paramstyle="pyformat")
2323
self._pool = None
2424

25+
def _get_connection_kwargs(self) -> dict:
26+
options = self._database_url.options
27+
28+
kwargs = {}
29+
min_size = options.get('min_size')
30+
max_size = options.get('max_size')
31+
ssl = options.get('ssl')
32+
33+
if min_size is not None:
34+
kwargs['minsize'] = int(min_size)
35+
if max_size is not None:
36+
kwargs['maxsize'] = int(max_size)
37+
if ssl is not None:
38+
kwargs['ssl'] = {'true': True, 'false': False}[ssl.lower()]
39+
return kwargs
40+
2541
async def connect(self) -> None:
2642
assert self._pool is None, "DatabaseBackend is already running"
43+
kwargs = self._get_connection_kwargs()
2744
self._pool = await aiomysql.create_pool(
2845
host=self._database_url.hostname,
2946
port=self._database_url.port or 3306,
3047
user=self._database_url.username or getpass.getuser(),
3148
password=self._database_url.password,
3249
db=self._database_url.database,
3350
autocommit=True,
51+
**kwargs
3452
)
3553

3654
async def disconnect(self) -> None:

databases/backends/postgres.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616

1717

1818
class PostgresBackend(DatabaseBackend):
19-
def __init__(self, database_url: DatabaseURL) -> None:
20-
self._database_url = database_url
19+
def __init__(self, database_url: typing.Union[DatabaseURL, str]) -> None:
20+
self._database_url = DatabaseURL(database_url)
2121
self._dialect = self._get_dialect()
2222
self._pool = None
2323

@@ -33,9 +33,26 @@ def _get_dialect(self) -> Dialect:
3333

3434
return dialect
3535

36+
def _get_connection_kwargs(self) -> dict:
37+
options = self._database_url.options
38+
39+
kwargs = {}
40+
min_size = options.get('min_size')
41+
max_size = options.get('max_size')
42+
ssl = options.get('ssl')
43+
44+
if min_size is not None:
45+
kwargs['min_size'] = int(min_size)
46+
if max_size is not None:
47+
kwargs['max_size'] = int(max_size)
48+
if ssl is not None:
49+
kwargs['ssl'] = {'true': True, 'false': False}[ssl.lower()]
50+
return kwargs
51+
3652
async def connect(self) -> None:
3753
assert self._pool is None, "DatabaseBackend is already running"
38-
self._pool = await asyncpg.create_pool(str(self._database_url))
54+
kwargs = self._get_connection_kwargs()
55+
self._pool = await asyncpg.create_pool(str(self._database_url), **kwargs)
3956

4057
async def disconnect(self) -> None:
4158
assert self._pool is not None, "DatabaseBackend is not running"

databases/backends/sqlite.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@
1616

1717

1818
class SQLiteBackend(DatabaseBackend):
19-
def __init__(self, database_url: DatabaseURL) -> None:
20-
self._database_url = database_url
19+
def __init__(self, database_url: typing.Union[DatabaseURL, str]) -> None:
20+
self._database_url = DatabaseURL(database_url)
2121
self._dialect = pysqlite.dialect(paramstyle="qmark")
2222
self._pool = SQLitePool(database_url)
2323

databases/core.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import sys
44
import typing
55
from types import TracebackType
6-
from urllib.parse import SplitResult, urlsplit
6+
from urllib.parse import SplitResult, urlsplit, parse_qsl
77

88
from sqlalchemy.engine import RowProxy
99
from sqlalchemy.sql import ClauseElement
@@ -295,6 +295,12 @@ def netloc(self) -> typing.Optional[str]:
295295
def database(self) -> str:
296296
return self.components.path.lstrip("/")
297297

298+
@property
299+
def options(self) -> dict:
300+
if not hasattr(self, "_options"):
301+
self._options = dict(parse_qsl(self.components.query))
302+
return self._options
303+
298304
def replace(self, **kwargs: typing.Any) -> "DatabaseURL":
299305
if (
300306
"username" in kwargs

tests/test_connection_options.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
"""
2+
Unit tests for the backend connection arguments.
3+
"""
4+
5+
from databases.backends.mysql import MySQLBackend
6+
from databases.backends.postgres import PostgresBackend
7+
8+
9+
def test_postgres_pool_size():
10+
backend = PostgresBackend("postgres://localhost/database?min_size=1&max_size=20")
11+
kwargs = backend._get_connection_kwargs()
12+
assert kwargs == {
13+
'min_size': 1,
14+
'max_size': 20
15+
}
16+
17+
18+
def test_postgres_ssl():
19+
backend = PostgresBackend("postgres://localhost/database?ssl=true")
20+
kwargs = backend._get_connection_kwargs()
21+
assert kwargs == {
22+
'ssl': True,
23+
}
24+
25+
26+
def test_mysql_pool_size():
27+
backend = MySQLBackend("mysql://localhost/database?min_size=1&max_size=20")
28+
kwargs = backend._get_connection_kwargs()
29+
assert kwargs == {
30+
'minsize': 1,
31+
'maxsize': 20
32+
}
33+
34+
35+
def test_mysql_ssl():
36+
backend = MySQLBackend("postgres://localhost/database?ssl=true")
37+
kwargs = backend._get_connection_kwargs()
38+
assert kwargs == {
39+
'ssl': True,
40+
}

tests/test_database_url.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ def test_database_url_properties():
2323
assert u.database == "mydatabase"
2424

2525

26+
def test_database_url_properties():
27+
u = DatabaseURL("postgresql://localhost/mydatabase?pool_size=20&ssl=true")
28+
assert u.options == {"pool_size": "20", "ssl": "true"}
29+
30+
2631
def test_replace_database_url_components():
2732
u = DatabaseURL("postgresql://localhost/mydatabase")
2833

0 commit comments

Comments
 (0)