Skip to content

Commit 9be8373

Browse files
committed
Add create_engine function for SQLAlchemy
1 parent a3fadf7 commit 9be8373

3 files changed

Lines changed: 93 additions & 0 deletions

File tree

docs/src/api.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,17 @@ package. It connects to a SingleStore database using either
1515
`DB-API <https://peps.python.org/pep-0249/>`_ compliant parameters,
1616
or a connection string in the form of a URL.
1717

18+
The :func:`create_engine` function is used with the SQLAlchemy package
19+
to create an SQLAlchemy engine for SingleStoreDB connections. This is
20+
primarily for use in environments where the connection parameters are
21+
stored in environment variables so that you can create SingleStoreDB
22+
connections without specifying any parameters in the code itself.
23+
1824
.. autosummary::
1925
:toctree: generated/
2026

2127
connect
28+
create_engine
2229

2330

2431
Connection

singlestoredb/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
__version__ = '0.8.0'
1717

18+
from .alchemy import create_engine
1819
from .config import options, get_option, set_option, describe_option
1920
from .connection import connect, apilevel, threadsafety, paramstyle
2021
from .exceptions import (

singlestoredb/alchemy/__init__.py

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#!/usr/bin/env python3
2+
import inspect
3+
from typing import Any
4+
from urllib.parse import quote
5+
6+
try:
7+
import sqlalchemy_singlestoredb # noqa: F401
8+
import sqlalchemy
9+
has_sqlalchemy = True
10+
except ImportError:
11+
has_sqlalchemy = False
12+
13+
from ..connection import build_params
14+
from ..connection import connect
15+
16+
17+
def create_engine(*args: Any, **kwargs: Any) -> Any:
18+
"""
19+
Create an SQLAlchemy engine for SingleStoreDB.
20+
21+
Parameters
22+
----------
23+
**kwargs : Any
24+
The parameters taken here are the same as for
25+
`sqlalchemy.create_engine`. However, this function can be
26+
called without any parameters in order to inherit parameters
27+
set by environment variables or parameters set in by
28+
options in Python code.
29+
30+
See Also
31+
--------
32+
`sqlalchemy.create_engine`
33+
34+
Returns
35+
-------
36+
SQLAlchemy engine
37+
38+
"""
39+
if not has_sqlalchemy:
40+
raise RuntimeError('sqlalchemy_singlestoredb package is not installed')
41+
42+
if len(args) > 1:
43+
raise ValueError(
44+
'`args` can only have a single element '
45+
'containing the database URL',
46+
)
47+
48+
if args:
49+
kwargs['host'] = args[0]
50+
51+
conn_params = {}
52+
sa_params = {}
53+
54+
conn_args = inspect.getfullargspec(connect).args
55+
56+
for key, value in kwargs.items():
57+
if key in conn_args:
58+
conn_params[key] = value
59+
else:
60+
sa_params[key] = value
61+
62+
params = build_params(**conn_params)
63+
driver = params.pop('driver', None)
64+
host = params.pop('host')
65+
port = params.pop('port')
66+
user = params.pop('user', None)
67+
password = params.pop('password', None)
68+
database = params.pop('database', '')
69+
70+
if not driver:
71+
driver = 'singlestoredb+mysql'
72+
elif not driver.startswith('singlestoredb'):
73+
driver = f'singlestoredb+{driver}'
74+
75+
if user is not None and password is not None:
76+
url = f'{driver}://{quote(user)}:{quote(password)}@' \
77+
f'{host}:{port}/{quote(database)}'
78+
elif user is not None:
79+
url = f'{driver}://{quote(user)}@{host}:{port}/{quote(database)}'
80+
elif password is not None:
81+
url = f'{driver}://:{quote(password)}@{host}:{port}/{quote(database)}'
82+
else:
83+
url = f'{driver}://{host}:{port}/{quote(database)}'
84+
85+
return sqlalchemy.create_engine(url, connect_args=params, **sa_params)

0 commit comments

Comments
 (0)