wherobots-python-dbapi 0.25.2__tar.gz → 0.25.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {wherobots_python_dbapi-0.25.2 → wherobots_python_dbapi-0.25.4}/PKG-INFO +41 -3
- {wherobots_python_dbapi-0.25.2 → wherobots_python_dbapi-0.25.4}/README.md +38 -0
- {wherobots_python_dbapi-0.25.2 → wherobots_python_dbapi-0.25.4}/pyproject.toml +3 -3
- {wherobots_python_dbapi-0.25.2 → wherobots_python_dbapi-0.25.4}/wherobots/db/cursor.py +54 -1
- {wherobots_python_dbapi-0.25.2 → wherobots_python_dbapi-0.25.4}/.gitignore +0 -0
- {wherobots_python_dbapi-0.25.2 → wherobots_python_dbapi-0.25.4}/LICENSE +0 -0
- {wherobots_python_dbapi-0.25.2 → wherobots_python_dbapi-0.25.4}/wherobots/__init__.py +0 -0
- {wherobots_python_dbapi-0.25.2 → wherobots_python_dbapi-0.25.4}/wherobots/db/__init__.py +0 -0
- {wherobots_python_dbapi-0.25.2 → wherobots_python_dbapi-0.25.4}/wherobots/db/connection.py +0 -0
- {wherobots_python_dbapi-0.25.2 → wherobots_python_dbapi-0.25.4}/wherobots/db/constants.py +0 -0
- {wherobots_python_dbapi-0.25.2 → wherobots_python_dbapi-0.25.4}/wherobots/db/driver.py +0 -0
- {wherobots_python_dbapi-0.25.2 → wherobots_python_dbapi-0.25.4}/wherobots/db/errors.py +0 -0
- {wherobots_python_dbapi-0.25.2 → wherobots_python_dbapi-0.25.4}/wherobots/db/models.py +0 -0
- {wherobots_python_dbapi-0.25.2 → wherobots_python_dbapi-0.25.4}/wherobots/db/region.py +0 -0
- {wherobots_python_dbapi-0.25.2 → wherobots_python_dbapi-0.25.4}/wherobots/db/runtime.py +0 -0
- {wherobots_python_dbapi-0.25.2 → wherobots_python_dbapi-0.25.4}/wherobots/db/session_type.py +0 -0
- {wherobots_python_dbapi-0.25.2 → wherobots_python_dbapi-0.25.4}/wherobots/db/types.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: wherobots-python-dbapi
|
|
3
|
-
Version: 0.25.
|
|
3
|
+
Version: 0.25.4
|
|
4
4
|
Summary: Python DB-API driver for Wherobots DB
|
|
5
5
|
Project-URL: Homepage, https://github.com/wherobots/wherobots-python-dbapi-driver
|
|
6
6
|
Project-URL: Tracker, https://github.com/wherobots/wherobots-python-dbapi-driver/issues
|
|
@@ -13,10 +13,10 @@ Requires-Dist: packaging
|
|
|
13
13
|
Requires-Dist: pandas
|
|
14
14
|
Requires-Dist: pandas-stubs>=2.0.3.230814
|
|
15
15
|
Requires-Dist: pyarrow>=14.0.2
|
|
16
|
-
Requires-Dist: requests>=2.
|
|
16
|
+
Requires-Dist: requests>=2.31.0
|
|
17
17
|
Requires-Dist: strenum<0.5,>=0.4.15
|
|
18
18
|
Requires-Dist: tenacity>=8.2.3
|
|
19
|
-
Requires-Dist: types-requests>=2.
|
|
19
|
+
Requires-Dist: types-requests>=2.31.0
|
|
20
20
|
Requires-Dist: websockets>=13.0
|
|
21
21
|
Provides-Extra: test
|
|
22
22
|
Requires-Dist: pytest>=8.0.2; extra == 'test'
|
|
@@ -28,6 +28,44 @@ Python DB-API implementation for Wherobots DB. This package implements a
|
|
|
28
28
|
PEP-0249 compatible driver to programmatically connect to a Wherobots DB
|
|
29
29
|
runtime and execute Spatial SQL queries.
|
|
30
30
|
|
|
31
|
+
## PEP 249 DB-API 2.0 Compliance
|
|
32
|
+
|
|
33
|
+
This driver implements the [PEP 249](https://peps.python.org/pep-0249/)
|
|
34
|
+
Python Database API Specification v2.0 and exposes the following
|
|
35
|
+
module-level globals:
|
|
36
|
+
|
|
37
|
+
| Global | Value | Meaning |
|
|
38
|
+
|---|---|---|
|
|
39
|
+
| `apilevel` | `"2.0"` | Supports DB-API 2.0 |
|
|
40
|
+
| `threadsafety` | `1` | Threads may share the module, but not connections |
|
|
41
|
+
| `paramstyle` | `"pyformat"` | Uses `%(name)s` named parameter markers |
|
|
42
|
+
|
|
43
|
+
### Parameterized queries
|
|
44
|
+
|
|
45
|
+
Use `%(name)s` markers in your SQL and pass a dictionary of parameter
|
|
46
|
+
values. The driver automatically quotes and escapes values based on
|
|
47
|
+
their Python type (strings are single-quoted, `None` becomes `NULL`,
|
|
48
|
+
booleans become `TRUE`/`FALSE`, and numeric types are passed through
|
|
49
|
+
unquoted):
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
curr.execute(
|
|
53
|
+
"SELECT * FROM places WHERE id = %(id)s AND category = %(cat)s",
|
|
54
|
+
parameters={"id": 42, "cat": "restaurant"},
|
|
55
|
+
)
|
|
56
|
+
# Produces: ... WHERE id = 42 AND category = 'restaurant'
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Literal `%` characters in SQL (e.g. `LIKE` wildcards) do not need
|
|
60
|
+
escaping and work alongside parameters:
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
curr.execute(
|
|
64
|
+
"SELECT * FROM places WHERE name LIKE '%coffee%' AND city = %(city)s",
|
|
65
|
+
parameters={"city": "Seattle"},
|
|
66
|
+
)
|
|
67
|
+
```
|
|
68
|
+
|
|
31
69
|
## Installation
|
|
32
70
|
|
|
33
71
|
To add this library as a dependency in your Python project, use `uv add`
|
|
@@ -4,6 +4,44 @@ Python DB-API implementation for Wherobots DB. This package implements a
|
|
|
4
4
|
PEP-0249 compatible driver to programmatically connect to a Wherobots DB
|
|
5
5
|
runtime and execute Spatial SQL queries.
|
|
6
6
|
|
|
7
|
+
## PEP 249 DB-API 2.0 Compliance
|
|
8
|
+
|
|
9
|
+
This driver implements the [PEP 249](https://peps.python.org/pep-0249/)
|
|
10
|
+
Python Database API Specification v2.0 and exposes the following
|
|
11
|
+
module-level globals:
|
|
12
|
+
|
|
13
|
+
| Global | Value | Meaning |
|
|
14
|
+
|---|---|---|
|
|
15
|
+
| `apilevel` | `"2.0"` | Supports DB-API 2.0 |
|
|
16
|
+
| `threadsafety` | `1` | Threads may share the module, but not connections |
|
|
17
|
+
| `paramstyle` | `"pyformat"` | Uses `%(name)s` named parameter markers |
|
|
18
|
+
|
|
19
|
+
### Parameterized queries
|
|
20
|
+
|
|
21
|
+
Use `%(name)s` markers in your SQL and pass a dictionary of parameter
|
|
22
|
+
values. The driver automatically quotes and escapes values based on
|
|
23
|
+
their Python type (strings are single-quoted, `None` becomes `NULL`,
|
|
24
|
+
booleans become `TRUE`/`FALSE`, and numeric types are passed through
|
|
25
|
+
unquoted):
|
|
26
|
+
|
|
27
|
+
```python
|
|
28
|
+
curr.execute(
|
|
29
|
+
"SELECT * FROM places WHERE id = %(id)s AND category = %(cat)s",
|
|
30
|
+
parameters={"id": 42, "cat": "restaurant"},
|
|
31
|
+
)
|
|
32
|
+
# Produces: ... WHERE id = 42 AND category = 'restaurant'
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Literal `%` characters in SQL (e.g. `LIKE` wildcards) do not need
|
|
36
|
+
escaping and work alongside parameters:
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
curr.execute(
|
|
40
|
+
"SELECT * FROM places WHERE name LIKE '%coffee%' AND city = %(city)s",
|
|
41
|
+
parameters={"city": "Seattle"},
|
|
42
|
+
)
|
|
43
|
+
```
|
|
44
|
+
|
|
7
45
|
## Installation
|
|
8
46
|
|
|
9
47
|
To add this library as a dependency in your Python project, use `uv add`
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "wherobots-python-dbapi"
|
|
3
|
-
version = "0.25.
|
|
3
|
+
version = "0.25.4"
|
|
4
4
|
description = "Python DB-API driver for Wherobots DB"
|
|
5
5
|
authors = [{ name = "Maxime Petazzoni", email = "max@wherobots.com" }]
|
|
6
6
|
requires-python = ">=3.10, <4"
|
|
@@ -8,14 +8,14 @@ readme = "README.md"
|
|
|
8
8
|
license = "Apache-2.0"
|
|
9
9
|
dependencies = [
|
|
10
10
|
"packaging",
|
|
11
|
-
"requests>=2.
|
|
11
|
+
"requests>=2.31.0",
|
|
12
12
|
"websockets>=13.0",
|
|
13
13
|
"tenacity>=8.2.3",
|
|
14
14
|
"cbor2>=5.6.3",
|
|
15
15
|
"StrEnum>=0.4.15,<0.5",
|
|
16
16
|
"pyarrow>=14.0.2",
|
|
17
17
|
"pandas",
|
|
18
|
-
"types-requests>=2.
|
|
18
|
+
"types-requests>=2.31.0",
|
|
19
19
|
"pandas-stubs>=2.0.3.230814",
|
|
20
20
|
]
|
|
21
21
|
|
|
@@ -1,9 +1,60 @@
|
|
|
1
|
+
import math
|
|
1
2
|
import queue
|
|
3
|
+
import re
|
|
2
4
|
from typing import Any, List, Tuple, Dict
|
|
3
5
|
|
|
4
6
|
from .errors import ProgrammingError
|
|
5
7
|
from .models import ExecutionResult, Store, StoreResult
|
|
6
8
|
|
|
9
|
+
# Matches pyformat parameter markers: %(name)s
|
|
10
|
+
_PYFORMAT_RE = re.compile(r"%\(([^)]+)\)s")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _quote_value(value: Any) -> str:
|
|
14
|
+
"""Convert a Python value to a SQL literal string.
|
|
15
|
+
|
|
16
|
+
Handles quoting and escaping so that the interpolated SQL is syntactically
|
|
17
|
+
correct and safe from trivial injection.
|
|
18
|
+
"""
|
|
19
|
+
if value is None:
|
|
20
|
+
return "NULL"
|
|
21
|
+
# bool must be checked before int because bool is a subclass of int
|
|
22
|
+
if isinstance(value, bool):
|
|
23
|
+
return "TRUE" if value else "FALSE"
|
|
24
|
+
if isinstance(value, (int, float)):
|
|
25
|
+
if isinstance(value, float) and (math.isnan(value) or math.isinf(value)):
|
|
26
|
+
raise ProgrammingError(
|
|
27
|
+
f"Cannot convert float value {value!r} to SQL literal"
|
|
28
|
+
)
|
|
29
|
+
return str(value)
|
|
30
|
+
if isinstance(value, bytes):
|
|
31
|
+
return "X'" + value.hex() + "'"
|
|
32
|
+
# Everything else (str, date, datetime, etc.) is treated as a string literal
|
|
33
|
+
return "'" + str(value).replace("'", "''") + "'"
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def _substitute_parameters(operation: str, parameters: Dict[str, Any] | None) -> str:
|
|
37
|
+
"""Substitute pyformat parameters into a SQL operation string.
|
|
38
|
+
|
|
39
|
+
Uses regex to match only %(name)s tokens, leaving literal percent
|
|
40
|
+
characters (e.g. SQL LIKE wildcards) untouched. Values are quoted
|
|
41
|
+
according to their Python type so the resulting SQL is syntactically
|
|
42
|
+
correct (see :func:`_quote_value`).
|
|
43
|
+
"""
|
|
44
|
+
if not parameters:
|
|
45
|
+
return operation
|
|
46
|
+
|
|
47
|
+
def replacer(match: re.Match) -> str:
|
|
48
|
+
key = match.group(1)
|
|
49
|
+
if key not in parameters:
|
|
50
|
+
raise ProgrammingError(
|
|
51
|
+
f"Parameter '{key}' not found in provided parameters"
|
|
52
|
+
)
|
|
53
|
+
return _quote_value(parameters[key])
|
|
54
|
+
|
|
55
|
+
return _PYFORMAT_RE.sub(replacer, operation)
|
|
56
|
+
|
|
57
|
+
|
|
7
58
|
_TYPE_MAP = {
|
|
8
59
|
"object": "STRING",
|
|
9
60
|
"int64": "NUMBER",
|
|
@@ -99,7 +150,9 @@ class Cursor:
|
|
|
99
150
|
self.__description = None
|
|
100
151
|
|
|
101
152
|
self.__current_execution_id = self.__exec_fn(
|
|
102
|
-
operation
|
|
153
|
+
_substitute_parameters(operation, parameters),
|
|
154
|
+
self.__on_execution_result,
|
|
155
|
+
store,
|
|
103
156
|
)
|
|
104
157
|
|
|
105
158
|
def get_store_result(self) -> StoreResult | None:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{wherobots_python_dbapi-0.25.2 → wherobots_python_dbapi-0.25.4}/wherobots/db/session_type.py
RENAMED
|
File without changes
|
|
File without changes
|