ddsql 0.0.4__tar.gz → 0.1.0__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.
- {ddsql-0.0.4 → ddsql-0.1.0}/PKG-INFO +32 -26
- {ddsql-0.0.4 → ddsql-0.1.0}/README.md +25 -11
- {ddsql-0.0.4 → ddsql-0.1.0}/ddsql/adapter.py +16 -7
- {ddsql-0.0.4 → ddsql-0.1.0}/ddsql/query.py +17 -21
- {ddsql-0.0.4 → ddsql-0.1.0}/ddsql/serializers/base.py +3 -3
- {ddsql-0.0.4 → ddsql-0.1.0}/ddsql/serializers/clickhouse.py +1 -2
- {ddsql-0.0.4 → ddsql-0.1.0}/ddsql/serializers/postgres.py +1 -2
- {ddsql-0.0.4 → ddsql-0.1.0}/ddsql/sqlbase.py +7 -13
- ddsql-0.1.0/pyproject.toml +45 -0
- ddsql-0.1.0/pyproject.toml.orig +40 -0
- ddsql-0.0.4/pyproject.toml +0 -33
- {ddsql-0.0.4 → ddsql-0.1.0}/LICENSE +0 -0
- {ddsql-0.0.4 → ddsql-0.1.0}/ddsql/__init__.py +0 -0
- {ddsql-0.0.4 → ddsql-0.1.0}/ddsql/py.typed +0 -0
- {ddsql-0.0.4 → ddsql-0.1.0}/ddsql/serializers/__init__.py +0 -0
|
@@ -1,22 +1,14 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ddsql
|
|
3
|
-
Version: 0.0
|
|
3
|
+
Version: 0.1.0
|
|
4
4
|
Summary: SQL Query Library
|
|
5
|
-
License: MIT
|
|
6
|
-
License-File: LICENSE
|
|
7
5
|
Keywords: python,ddsql
|
|
8
6
|
Author: davyddd
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.14
|
|
18
|
-
Requires-Dist: ddutils (<0.2.0)
|
|
19
|
-
Requires-Dist: jinja2 (>=3.0.0,<4.0.0)
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
Requires-Dist: ddutils>=0.2.0,<0.3.0
|
|
10
|
+
Requires-Dist: jinja2>=3.0.0,<4.0.0
|
|
11
|
+
Requires-Python: >=3.11, <3.15
|
|
20
12
|
Project-URL: Repository, https://github.com/davyddd/ddsql
|
|
21
13
|
Description-Content-Type: text/markdown
|
|
22
14
|
|
|
@@ -38,6 +30,21 @@ Install the library using pip:
|
|
|
38
30
|
pip install ddsql
|
|
39
31
|
```
|
|
40
32
|
|
|
33
|
+
## Development
|
|
34
|
+
|
|
35
|
+
The project runs entirely in Docker. Requires Docker and [Fabric](https://www.fabfile.org/) on the host:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
fab build # build the dev image
|
|
39
|
+
fab tests # run pytest
|
|
40
|
+
fab linters # run ruff (with --fix), ty and complexipy
|
|
41
|
+
fab shell # IPython inside the container
|
|
42
|
+
fab bash # bash inside the container
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
This project was generated from [dd-lib-stub](https://github.com/davyddd/dd-lib-stub);
|
|
46
|
+
run `copier update` to pull in template updates.
|
|
47
|
+
|
|
41
48
|
## Serializer
|
|
42
49
|
|
|
43
50
|
The serializer converts Python types to their SQL representations.
|
|
@@ -177,7 +184,7 @@ which wraps raw database rows into the specified model (called internally by `Ad
|
|
|
177
184
|
|
|
178
185
|
Required parameters:
|
|
179
186
|
- **model** – a declarative class (e.g., dataclass) describing the output result structure;
|
|
180
|
-
- **text** or **path** – the SQL template source.
|
|
187
|
+
- **text** or **path** – the SQL template source (inline string or path to a file).
|
|
181
188
|
|
|
182
189
|
### Inline Template (text)
|
|
183
190
|
|
|
@@ -193,25 +200,24 @@ query = Query(
|
|
|
193
200
|
|
|
194
201
|
### File Template (path)
|
|
195
202
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
```bash
|
|
199
|
-
export SQL_TEMPLATES_DIR=/app/src/templates/sql/
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
Then use a relative path:
|
|
203
|
+
Pass the path to the SQL file as `Path`. The file is checked at construction time, so a wrong path fails
|
|
204
|
+
on import rather than on the first query:
|
|
203
205
|
|
|
204
206
|
```python
|
|
207
|
+
from pathlib import Path
|
|
208
|
+
|
|
205
209
|
from ddsql.query import Query
|
|
206
210
|
|
|
211
|
+
SQL_TEMPLATES_DIR = Path(__file__).parent / 'templates' / 'sql'
|
|
207
212
|
|
|
208
|
-
# Loads template from /app/src/templates/sql/users/get_by_id.sql
|
|
209
213
|
query = Query(
|
|
210
|
-
model=User,
|
|
211
|
-
path='users/get_by_id.sql'
|
|
214
|
+
model=User,
|
|
215
|
+
path=SQL_TEMPLATES_DIR / 'users' / 'get_by_id.sql',
|
|
212
216
|
)
|
|
213
217
|
```
|
|
214
218
|
|
|
219
|
+
`{% include %}` and `{% import %}` inside the template resolve relative to the template's directory.
|
|
220
|
+
|
|
215
221
|
### Result
|
|
216
222
|
|
|
217
223
|
The result of query execution is a `Result` object that wraps the data into the specified model:
|
|
@@ -273,4 +279,4 @@ async def get_users():
|
|
|
273
279
|
.execute()
|
|
274
280
|
)
|
|
275
281
|
return result.get_list()
|
|
276
|
-
```
|
|
282
|
+
```
|
|
@@ -16,6 +16,21 @@ Install the library using pip:
|
|
|
16
16
|
pip install ddsql
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
+
## Development
|
|
20
|
+
|
|
21
|
+
The project runs entirely in Docker. Requires Docker and [Fabric](https://www.fabfile.org/) on the host:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
fab build # build the dev image
|
|
25
|
+
fab tests # run pytest
|
|
26
|
+
fab linters # run ruff (with --fix), ty and complexipy
|
|
27
|
+
fab shell # IPython inside the container
|
|
28
|
+
fab bash # bash inside the container
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
This project was generated from [dd-lib-stub](https://github.com/davyddd/dd-lib-stub);
|
|
32
|
+
run `copier update` to pull in template updates.
|
|
33
|
+
|
|
19
34
|
## Serializer
|
|
20
35
|
|
|
21
36
|
The serializer converts Python types to their SQL representations.
|
|
@@ -155,7 +170,7 @@ which wraps raw database rows into the specified model (called internally by `Ad
|
|
|
155
170
|
|
|
156
171
|
Required parameters:
|
|
157
172
|
- **model** – a declarative class (e.g., dataclass) describing the output result structure;
|
|
158
|
-
- **text** or **path** – the SQL template source.
|
|
173
|
+
- **text** or **path** – the SQL template source (inline string or path to a file).
|
|
159
174
|
|
|
160
175
|
### Inline Template (text)
|
|
161
176
|
|
|
@@ -171,25 +186,24 @@ query = Query(
|
|
|
171
186
|
|
|
172
187
|
### File Template (path)
|
|
173
188
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
```bash
|
|
177
|
-
export SQL_TEMPLATES_DIR=/app/src/templates/sql/
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
Then use a relative path:
|
|
189
|
+
Pass the path to the SQL file as `Path`. The file is checked at construction time, so a wrong path fails
|
|
190
|
+
on import rather than on the first query:
|
|
181
191
|
|
|
182
192
|
```python
|
|
193
|
+
from pathlib import Path
|
|
194
|
+
|
|
183
195
|
from ddsql.query import Query
|
|
184
196
|
|
|
197
|
+
SQL_TEMPLATES_DIR = Path(__file__).parent / 'templates' / 'sql'
|
|
185
198
|
|
|
186
|
-
# Loads template from /app/src/templates/sql/users/get_by_id.sql
|
|
187
199
|
query = Query(
|
|
188
|
-
model=User,
|
|
189
|
-
path='users/get_by_id.sql'
|
|
200
|
+
model=User,
|
|
201
|
+
path=SQL_TEMPLATES_DIR / 'users' / 'get_by_id.sql',
|
|
190
202
|
)
|
|
191
203
|
```
|
|
192
204
|
|
|
205
|
+
`{% include %}` and `{% import %}` inside the template resolve relative to the template's directory.
|
|
206
|
+
|
|
193
207
|
### Result
|
|
194
208
|
|
|
195
209
|
The result of query execution is a `Result` object that wraps the data into the specified model:
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from abc import ABC, abstractmethod
|
|
4
|
-
from typing import TYPE_CHECKING, Any,
|
|
4
|
+
from typing import TYPE_CHECKING, Any, Generic, TypeVar, overload
|
|
5
5
|
|
|
6
6
|
from ddutils.annotation_helpers import is_subclass
|
|
7
7
|
|
|
8
8
|
from ddsql.serializers import BaseSerializer
|
|
9
9
|
|
|
10
10
|
if TYPE_CHECKING:
|
|
11
|
+
from collections.abc import Sequence
|
|
12
|
+
|
|
11
13
|
from ddsql.query import Result
|
|
12
14
|
from ddsql.sqlbase import SQLBase
|
|
13
15
|
|
|
@@ -15,7 +17,6 @@ if TYPE_CHECKING:
|
|
|
15
17
|
class Adapter(ABC):
|
|
16
18
|
serializer: BaseSerializer
|
|
17
19
|
|
|
18
|
-
@classmethod
|
|
19
20
|
def __init_subclass__(cls, **kwargs):
|
|
20
21
|
serializer = getattr(cls, 'serializer', None)
|
|
21
22
|
serializer_class = getattr(serializer, '__class__', None)
|
|
@@ -36,20 +37,28 @@ class Adapter(ABC):
|
|
|
36
37
|
return self.sql.query.build_result(await self._execute())
|
|
37
38
|
|
|
38
39
|
@abstractmethod
|
|
39
|
-
async def _execute(self) -> Sequence[
|
|
40
|
-
...
|
|
40
|
+
async def _execute(self) -> Sequence[dict[str, Any]]: ...
|
|
41
41
|
|
|
42
42
|
|
|
43
43
|
AdapterT = TypeVar('AdapterT', bound=Adapter)
|
|
44
44
|
|
|
45
45
|
|
|
46
46
|
class AdapterDescriptor(Generic[AdapterT]):
|
|
47
|
-
adapter_class:
|
|
47
|
+
adapter_class: type[AdapterT]
|
|
48
48
|
|
|
49
|
-
def __init__(self, adapter_class:
|
|
49
|
+
def __init__(self, adapter_class: type[AdapterT]):
|
|
50
50
|
self.adapter_class = adapter_class
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
@overload
|
|
53
|
+
def __get__(self, sql: None, sql_class: type[SQLBase]) -> AdapterDescriptor[AdapterT]: ...
|
|
54
|
+
|
|
55
|
+
@overload
|
|
56
|
+
def __get__(self, sql: SQLBase, sql_class: type[SQLBase] | None = None) -> AdapterT: ...
|
|
57
|
+
|
|
58
|
+
def __get__(self, sql: SQLBase | None, sql_class: type[SQLBase] | None = None) -> AdapterT | AdapterDescriptor[AdapterT]:
|
|
59
|
+
# accessed on the class, like `SQL.postgres`: return the descriptor itself, as `property` does
|
|
60
|
+
if sql is None:
|
|
61
|
+
return self
|
|
53
62
|
return self.adapter_class(sql)
|
|
54
63
|
|
|
55
64
|
|
|
@@ -1,55 +1,51 @@
|
|
|
1
|
-
import
|
|
1
|
+
from collections.abc import Sequence
|
|
2
2
|
from pathlib import Path
|
|
3
|
-
from typing import Any,
|
|
3
|
+
from typing import Any, Generic, TypeVar
|
|
4
4
|
|
|
5
5
|
from jinja2 import Environment, FileSystemLoader, Template
|
|
6
6
|
|
|
7
|
-
SQL_TEMPLATES_DIR = os.getenv('SQL_TEMPLATES_DIR')
|
|
8
|
-
|
|
9
|
-
|
|
10
7
|
DataT = TypeVar('DataT')
|
|
11
8
|
|
|
12
9
|
|
|
13
10
|
class Result(Generic[DataT]):
|
|
14
11
|
rows: Sequence[dict[str, Any]]
|
|
15
|
-
model:
|
|
12
|
+
model: type[DataT]
|
|
16
13
|
|
|
17
|
-
def __init__(self, rows: Sequence[dict[str, Any]], model:
|
|
14
|
+
def __init__(self, rows: Sequence[dict[str, Any]], model: type[DataT]):
|
|
18
15
|
self.rows = rows
|
|
19
16
|
self.model = model
|
|
20
17
|
|
|
21
|
-
def get(self) ->
|
|
18
|
+
def get(self) -> DataT | None:
|
|
22
19
|
if not self.rows:
|
|
23
20
|
return None
|
|
24
21
|
return self.model(**self.rows[0])
|
|
25
22
|
|
|
26
|
-
def get_list(self) ->
|
|
23
|
+
def get_list(self) -> tuple[DataT, ...]:
|
|
27
24
|
return tuple(self.model(**row) for row in self.rows)
|
|
28
25
|
|
|
29
26
|
|
|
30
27
|
class Query(Generic[DataT]):
|
|
31
|
-
model:
|
|
28
|
+
model: type[DataT]
|
|
32
29
|
template: Template
|
|
33
30
|
|
|
34
|
-
def __init__(self, model:
|
|
31
|
+
def __init__(self, model: type[DataT], text: str | None = None, path: Path | None = None):
|
|
35
32
|
self.model = model
|
|
36
33
|
|
|
37
34
|
self.template = self.get_template(text, path)
|
|
38
35
|
|
|
39
36
|
@staticmethod
|
|
40
|
-
def get_template(text:
|
|
37
|
+
def get_template(text: str | None = None, path: Path | None = None) -> Template:
|
|
41
38
|
if text:
|
|
42
|
-
file_system_loader =
|
|
39
|
+
file_system_loader = None
|
|
43
40
|
method = 'from_string'
|
|
44
41
|
query = text
|
|
45
42
|
elif path:
|
|
46
|
-
if
|
|
47
|
-
raise
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
file_system_loader = FileSystemLoader(Path(SQL_TEMPLATES_DIR))
|
|
43
|
+
if not path.is_file():
|
|
44
|
+
raise FileNotFoundError(f'SQL template not found: {path.resolve()}')
|
|
45
|
+
# the loader is rooted at the template directory, so `{% include %}` resolves relative to the file
|
|
46
|
+
file_system_loader = FileSystemLoader(path.parent)
|
|
51
47
|
method = 'get_template'
|
|
52
|
-
query = path
|
|
48
|
+
query = path.name
|
|
53
49
|
else:
|
|
54
50
|
raise ValueError('One of `text` or `path` must be specified')
|
|
55
51
|
|
|
@@ -59,7 +55,7 @@ class Query(Generic[DataT]):
|
|
|
59
55
|
|
|
60
56
|
return getattr(environment, method)(query)
|
|
61
57
|
|
|
62
|
-
def update_globals(self, envs:
|
|
58
|
+
def update_globals(self, envs: dict[str, Any] | None = None):
|
|
63
59
|
if envs:
|
|
64
60
|
self.template.environment.globals.update(envs)
|
|
65
61
|
|
|
@@ -68,7 +64,7 @@ class Query(Generic[DataT]):
|
|
|
68
64
|
strings = sql.split('\n')
|
|
69
65
|
return '\n'.join([string.strip() for string in strings])
|
|
70
66
|
|
|
71
|
-
async def render_template(self, params:
|
|
67
|
+
async def render_template(self, params: dict[str, Any], template_functions: dict[str, Any] | None = None) -> str:
|
|
72
68
|
self.update_globals(template_functions)
|
|
73
69
|
|
|
74
70
|
rendered_template = await self.template.render_async(**params)
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
from collections.abc import Callable, Collection, Mapping
|
|
2
2
|
from datetime import date, datetime
|
|
3
3
|
from decimal import Decimal
|
|
4
|
-
from typing import Any
|
|
4
|
+
from typing import Any
|
|
5
5
|
from uuid import UUID
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class BaseSerializer:
|
|
9
9
|
@property
|
|
10
|
-
def template_functions(self) ->
|
|
10
|
+
def template_functions(self) -> dict[str, Callable[[Any], str]]:
|
|
11
11
|
return {'serialize_value': self.serialize_value}
|
|
12
12
|
|
|
13
13
|
def serialize_value(self, value: Any) -> str:
|
|
@@ -41,7 +41,7 @@ class BaseSerializer:
|
|
|
41
41
|
return f'{value}'.lower()
|
|
42
42
|
|
|
43
43
|
@staticmethod
|
|
44
|
-
def serialize_number(value:
|
|
44
|
+
def serialize_number(value: int | float | Decimal) -> str:
|
|
45
45
|
return f'{value}'
|
|
46
46
|
|
|
47
47
|
@staticmethod
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
from datetime import date, datetime
|
|
2
|
-
from typing import Dict
|
|
3
2
|
from uuid import UUID
|
|
4
3
|
|
|
5
4
|
from ddsql.serializers import BaseSerializer
|
|
6
5
|
|
|
7
6
|
|
|
8
|
-
def _build_escape_translation() ->
|
|
7
|
+
def _build_escape_translation() -> dict[int, str]:
|
|
9
8
|
# https://clickhouse.com/docs/en/sql-reference/syntax#string
|
|
10
9
|
translation = {
|
|
11
10
|
ord('\\'): '\\\\',
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import re
|
|
2
2
|
from datetime import date, datetime
|
|
3
|
-
from typing import Dict
|
|
4
3
|
from uuid import UUID
|
|
5
4
|
|
|
6
5
|
from ddsql.serializers import BaseSerializer
|
|
@@ -11,7 +10,7 @@ from ddsql.serializers import BaseSerializer
|
|
|
11
10
|
_ESCAPE_SYNTAX_REQUIRED = re.compile(r'[\\\x00-\x1F\x7F]')
|
|
12
11
|
|
|
13
12
|
|
|
14
|
-
def _build_escape_translation() ->
|
|
13
|
+
def _build_escape_translation() -> dict[int, str]:
|
|
15
14
|
# https://www.postgresql.org/docs/current/sql-syntax-lexical.html#SQL-SYNTAX-STRINGS-ESCAPE
|
|
16
15
|
translation = {
|
|
17
16
|
ord('\\'): '\\\\',
|
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from abc import ABC
|
|
4
|
-
from typing import TYPE_CHECKING, Any,
|
|
4
|
+
from typing import TYPE_CHECKING, Any, TypeVar
|
|
5
5
|
|
|
6
|
-
from ddutils.annotation_helpers import is_subclass
|
|
7
6
|
from ddutils.class_helpers import classproperty
|
|
8
7
|
|
|
9
|
-
from ddsql.adapter import
|
|
8
|
+
from ddsql.adapter import AdapterDescriptor
|
|
10
9
|
|
|
11
10
|
if TYPE_CHECKING:
|
|
12
11
|
from ddsql.query import Query
|
|
@@ -29,22 +28,17 @@ class SQLBase(ABC):
|
|
|
29
28
|
"""
|
|
30
29
|
|
|
31
30
|
query: Query
|
|
32
|
-
params:
|
|
31
|
+
params: dict[str, Any]
|
|
33
32
|
|
|
34
|
-
@classmethod
|
|
35
33
|
def __init_subclass__(cls, **kwargs):
|
|
36
34
|
if not cls.has_adapters:
|
|
37
35
|
raise NotImplementedError('Subclasses must define at least one adapter')
|
|
38
36
|
|
|
39
37
|
@classproperty
|
|
40
|
-
def has_adapters(cls) -> bool:
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
if adapter_class and is_subclass(adapter_class, Adapter):
|
|
45
|
-
return True
|
|
46
|
-
|
|
47
|
-
return False
|
|
38
|
+
def has_adapters(cls: type[SQLBase]) -> bool:
|
|
39
|
+
# Descriptors are looked up in the class dictionaries along the MRO, so inherited adapters count
|
|
40
|
+
# and no adapter gets instantiated just for the check
|
|
41
|
+
return any(isinstance(value, AdapterDescriptor) for klass in cls.__mro__ for value in vars(klass).values())
|
|
48
42
|
|
|
49
43
|
def __init__(self, query: Query) -> None:
|
|
50
44
|
self.query = query
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "ddsql"
|
|
3
|
+
description = "SQL Query Library"
|
|
4
|
+
version = "0.1.0"
|
|
5
|
+
license = "MIT"
|
|
6
|
+
license-files = ["LICENSE"]
|
|
7
|
+
readme = "README.md"
|
|
8
|
+
requires-python = ">=3.11,<3.15"
|
|
9
|
+
keywords = [
|
|
10
|
+
"python",
|
|
11
|
+
"ddsql",
|
|
12
|
+
]
|
|
13
|
+
dependencies = [
|
|
14
|
+
"ddutils>=0.2.0,<0.3.0",
|
|
15
|
+
"jinja2>=3.0.0,<4.0.0",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
[[project.authors]]
|
|
19
|
+
name = "davyddd"
|
|
20
|
+
|
|
21
|
+
[project.urls]
|
|
22
|
+
Repository = "https://github.com/davyddd/ddsql"
|
|
23
|
+
|
|
24
|
+
[dependency-groups]
|
|
25
|
+
dev = [
|
|
26
|
+
"ipdb==0.13.13",
|
|
27
|
+
"ipython==9.16.1",
|
|
28
|
+
]
|
|
29
|
+
test = [
|
|
30
|
+
"pytest==9.0.3",
|
|
31
|
+
"pytest-cov==5.0.0",
|
|
32
|
+
"parameterized==0.9.0",
|
|
33
|
+
]
|
|
34
|
+
linter = [
|
|
35
|
+
"ruff==0.15.10",
|
|
36
|
+
"ty==0.0.15",
|
|
37
|
+
"complexipy==8.0.1",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
[tool.uv.build-backend]
|
|
41
|
+
module-root = ""
|
|
42
|
+
|
|
43
|
+
[build-system]
|
|
44
|
+
requires = ["uv_build>=0.12.0,<0.13.0"]
|
|
45
|
+
build-backend = "uv_build"
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "ddsql"
|
|
3
|
+
description = "SQL Query Library"
|
|
4
|
+
version = "0.1.0"
|
|
5
|
+
authors = [{ name = "davyddd" }]
|
|
6
|
+
license = "MIT"
|
|
7
|
+
license-files = ["LICENSE"]
|
|
8
|
+
readme = "README.md"
|
|
9
|
+
requires-python = ">=3.11,<3.15"
|
|
10
|
+
keywords = ["python", "ddsql"]
|
|
11
|
+
dependencies = [
|
|
12
|
+
"ddutils>=0.2.0,<0.3.0",
|
|
13
|
+
"jinja2>=3.0.0,<4.0.0",
|
|
14
|
+
]
|
|
15
|
+
|
|
16
|
+
[project.urls]
|
|
17
|
+
Repository = "https://github.com/davyddd/ddsql"
|
|
18
|
+
|
|
19
|
+
[dependency-groups]
|
|
20
|
+
dev = [
|
|
21
|
+
"ipdb==0.13.13",
|
|
22
|
+
"ipython==9.16.1",
|
|
23
|
+
]
|
|
24
|
+
test = [
|
|
25
|
+
"pytest==9.0.3",
|
|
26
|
+
"pytest-cov==5.0.0",
|
|
27
|
+
"parameterized==0.9.0",
|
|
28
|
+
]
|
|
29
|
+
linter = [
|
|
30
|
+
"ruff==0.15.10",
|
|
31
|
+
"ty==0.0.15",
|
|
32
|
+
"complexipy==8.0.1",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[tool.uv.build-backend]
|
|
36
|
+
module-root = ""
|
|
37
|
+
|
|
38
|
+
[build-system]
|
|
39
|
+
requires = ["uv_build>=0.12.0,<0.13.0"]
|
|
40
|
+
build-backend = "uv_build"
|
ddsql-0.0.4/pyproject.toml
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
[tool.poetry]
|
|
2
|
-
name = "ddsql"
|
|
3
|
-
description = "SQL Query Library"
|
|
4
|
-
version = "0.0.4"
|
|
5
|
-
authors = ["davyddd"]
|
|
6
|
-
license = "MIT"
|
|
7
|
-
repository = "https://github.com/davyddd/ddsql"
|
|
8
|
-
readme = "README.md"
|
|
9
|
-
keywords = ["python", "ddsql"]
|
|
10
|
-
packages = [{include = "ddsql"}]
|
|
11
|
-
|
|
12
|
-
[tool.poetry.dependencies]
|
|
13
|
-
python = ">=3.9,<3.15"
|
|
14
|
-
ddutils = "<0.2.0"
|
|
15
|
-
jinja2 = ">=3.0.0,<4.0.0"
|
|
16
|
-
|
|
17
|
-
[tool.poetry.group.dev.dependencies]
|
|
18
|
-
ipdb = "0.13.9"
|
|
19
|
-
ipython = "8.12.3"
|
|
20
|
-
|
|
21
|
-
[tool.poetry.group.test.dependencies]
|
|
22
|
-
pytest = "8.1.1"
|
|
23
|
-
pytest-cov = "5.0.0"
|
|
24
|
-
parameterized = "0.9.0"
|
|
25
|
-
typing-extensions = "^4.12.2"
|
|
26
|
-
|
|
27
|
-
[tool.poetry.group.linter.dependencies]
|
|
28
|
-
mypy = "1.18.2"
|
|
29
|
-
ruff = "0.14.4"
|
|
30
|
-
|
|
31
|
-
[build-system]
|
|
32
|
-
requires = ["poetry-core>=1.0.0"]
|
|
33
|
-
build-backend = "poetry.core.masonry.api"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|