ormlambda 2.8.0__tar.gz → 2.9.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.
- {ormlambda-2.8.0 → ormlambda-2.9.0}/PKG-INFO +3 -2
- {ormlambda-2.8.0 → ormlambda-2.9.0}/pyproject.toml +4 -2
- ormlambda-2.9.0/src/ormlambda/__init__.py +20 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/common/abstract_classes/abstract_model.py +16 -17
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/common/abstract_classes/decomposition_query.py +23 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/common/interfaces/IStatements.py +37 -30
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/databases/my_sql/clauses/insert.py +24 -12
- ormlambda-2.9.0/src/ormlambda/databases/my_sql/clauses/order.py +47 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/databases/my_sql/clauses/select.py +8 -4
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/databases/my_sql/clauses/update.py +11 -17
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/databases/my_sql/repository.py +56 -6
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/databases/my_sql/statements.py +26 -18
- ormlambda-2.9.0/src/ormlambda/utils/column.py +105 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/utils/dtypes.py +4 -12
- ormlambda-2.9.0/src/ormlambda/utils/fields.py +60 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/utils/table_constructor.py +67 -95
- ormlambda-2.8.0/src/ormlambda/__init__.py +0 -11
- ormlambda-2.8.0/src/ormlambda/databases/my_sql/clauses/order.py +0 -33
- ormlambda-2.8.0/src/ormlambda/utils/column.py +0 -66
- {ormlambda-2.8.0 → ormlambda-2.9.0}/LICENSE +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/README.md +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/common/__init__.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/common/abstract_classes/__init__.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/common/abstract_classes/non_query_base.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/common/abstract_classes/query_base.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/common/enums/__init__.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/common/enums/condition_types.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/common/enums/join_type.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/common/interfaces/IAggregate.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/common/interfaces/IDecompositionQuery.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/common/interfaces/INonQueryCommand.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/common/interfaces/IQueryCommand.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/common/interfaces/IRepositoryBase.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/common/interfaces/__init__.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/components/__init__.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/components/delete/IDelete.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/components/delete/__init__.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/components/delete/abstract_delete.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/components/insert/IInsert.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/components/insert/__init__.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/components/insert/abstract_insert.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/components/update/IUpdate.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/components/update/__init__.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/components/update/abstract_update.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/components/upsert/IUpsert.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/components/upsert/__init__.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/components/upsert/abstract_upsert.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/components/where/__init__.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/components/where/abstract_where.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/databases/__init__.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/databases/my_sql/__init__.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/databases/my_sql/clauses/__init__.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/databases/my_sql/clauses/count.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/databases/my_sql/clauses/create_database.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/databases/my_sql/clauses/delete.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/databases/my_sql/clauses/drop_database.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/databases/my_sql/clauses/drop_table.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/databases/my_sql/clauses/group_by.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/databases/my_sql/clauses/joins.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/databases/my_sql/clauses/limit.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/databases/my_sql/clauses/offset.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/databases/my_sql/clauses/upsert.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/databases/my_sql/clauses/where_condition.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/databases/my_sql/functions/__init__.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/databases/my_sql/functions/concat.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/databases/my_sql/functions/max.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/databases/my_sql/functions/min.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/databases/my_sql/functions/sum.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/model_base.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/utils/__init__.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/utils/foreign_key.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/utils/lambda_disassembler/__init__.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/utils/lambda_disassembler/dis_types.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/utils/lambda_disassembler/disassembler.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/utils/lambda_disassembler/dtypes.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/utils/lambda_disassembler/name_of.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/utils/lambda_disassembler/nested_element.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/utils/lambda_disassembler/tree_instruction.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/utils/module_tree/__init__.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/utils/module_tree/dfs_traversal.py +0 -0
- {ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/utils/module_tree/dynamic_module.py +0 -0
@@ -1,14 +1,15 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ormlambda
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.9.0
|
4
4
|
Summary: ORM designed to interact with the database (currently with MySQL) using lambda functions and nested functions
|
5
5
|
Author: p-hzamora
|
6
6
|
Author-email: p.hzamora@icloud.com
|
7
7
|
Requires-Python: >=3.12,<4.0
|
8
8
|
Classifier: Programming Language :: Python :: 3
|
9
9
|
Classifier: Programming Language :: Python :: 3.12
|
10
|
-
Requires-Dist: fluent-validation (
|
10
|
+
Requires-Dist: fluent-validation (==4.3.1)
|
11
11
|
Requires-Dist: mysql-connector-python (>=9.0.0,<10.0.0)
|
12
|
+
Requires-Dist: shapely (>=2.0.6,<3.0.0)
|
12
13
|
Description-Content-Type: text/markdown
|
13
14
|
|
14
15
|

|
@@ -3,7 +3,7 @@ line-length = 320
|
|
3
3
|
|
4
4
|
[tool.poetry]
|
5
5
|
name = "ormlambda"
|
6
|
-
version = "2.
|
6
|
+
version = "2.9.0"
|
7
7
|
description = "ORM designed to interact with the database (currently with MySQL) using lambda functions and nested functions"
|
8
8
|
authors = ["p-hzamora <p.hzamora@icloud.com>"]
|
9
9
|
readme = "README.md"
|
@@ -11,12 +11,14 @@ readme = "README.md"
|
|
11
11
|
[tool.poetry.dependencies]
|
12
12
|
python = "^3.12"
|
13
13
|
mysql-connector-python= "^9.0.0"
|
14
|
-
fluent-validation = "
|
14
|
+
fluent-validation = "4.3.1"
|
15
|
+
shapely = "^2.0.6"
|
15
16
|
|
16
17
|
[tool.poetry.group.test.dependencies]
|
17
18
|
pandas = "^2.2.2"
|
18
19
|
ruff = "^0.4.5"
|
19
20
|
python-decouple = "^3.8"
|
21
|
+
parameterized = "^0.9.0"
|
20
22
|
|
21
23
|
|
22
24
|
[build-system]
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# region enums
|
2
|
+
from .common.enums import (
|
3
|
+
JoinType as JoinType,
|
4
|
+
ConditionType as ConditionType,
|
5
|
+
)
|
6
|
+
from ormlambda.common.interfaces.IStatements import OrderType as OrderType
|
7
|
+
# endregion
|
8
|
+
|
9
|
+
from .common.abstract_classes import AbstractSQLStatements as AbstractSQLStatements
|
10
|
+
from .common.interfaces import IRepositoryBase as IRepositoryBase
|
11
|
+
from .utils import (
|
12
|
+
Table as Table,
|
13
|
+
Column as Column,
|
14
|
+
ForeignKey as ForeignKey,
|
15
|
+
)
|
16
|
+
from .utils.lambda_disassembler import (
|
17
|
+
Disassembler as Disassembler,
|
18
|
+
nameof as nameof,
|
19
|
+
)
|
20
|
+
from .model_base import BaseModel as BaseModel # COMMENT: to avoid relative import we need to import BaseModel after import Table,Column, ForeignKey, IRepositoryBase and Disassembler
|
@@ -10,7 +10,6 @@ from ormlambda.common.interfaces.IAggregate import IAggregate
|
|
10
10
|
|
11
11
|
if TYPE_CHECKING:
|
12
12
|
from ormlambda.common.abstract_classes.decomposition_query import DecompositionQueryBase
|
13
|
-
from ormlambda.components.select import ISelect
|
14
13
|
from ormlambda.common.abstract_classes.decomposition_query import ClauseInfo
|
15
14
|
|
16
15
|
|
@@ -46,11 +45,11 @@ class AbstractSQLStatements[T: Table, TRepo](IStatements_two_generic[T, TRepo]):
|
|
46
45
|
@override
|
47
46
|
def repository(self) -> IRepositoryBase[TRepo]: ...
|
48
47
|
|
49
|
-
def _return_flavour[TValue](self, query, flavour: Type[TValue]) -> tuple[TValue]:
|
50
|
-
return self._repository.read_sql(query, flavour=flavour)
|
48
|
+
def _return_flavour[TValue](self, query, flavour: Type[TValue], select) -> tuple[TValue]:
|
49
|
+
return self._repository.read_sql(query, flavour=flavour, model=self._model, select=select)
|
51
50
|
|
52
|
-
def _return_model(self, select
|
53
|
-
response_sql = self._repository.read_sql(query, flavour=dict) # store all columns of the SQL query
|
51
|
+
def _return_model(self, select, query: str):
|
52
|
+
response_sql = self._repository.read_sql(query, flavour=dict, model=self._model, select=select) # store all columns of the SQL query
|
54
53
|
|
55
54
|
if isinstance(response_sql, Iterable):
|
56
55
|
return ClusterQuery[T](select, response_sql).clean_response()
|
@@ -66,7 +65,16 @@ class ClusterQuery[T]:
|
|
66
65
|
self._select: DecompositionQueryBase[T] = select
|
67
66
|
self._response_sql: tuple[dict[str, Any]] = response_sql
|
68
67
|
|
69
|
-
def
|
68
|
+
def clean_response(self) -> tuple[dict[Type[Table], tuple[Table]]]:
|
69
|
+
tbl_dicc: dict[Type[Table], list[Table]] = self.__loop_foo()
|
70
|
+
|
71
|
+
# it not depend of flavour attr
|
72
|
+
for key, val in tbl_dicc.items():
|
73
|
+
tbl_dicc[key] = tuple(val)
|
74
|
+
|
75
|
+
return tuple(tbl_dicc.values())
|
76
|
+
|
77
|
+
def __loop_foo(self) -> dict[Type[Table], list[Table]]:
|
70
78
|
# We must ensure to get the valid attributes for each instance
|
71
79
|
table_initialize = defaultdict(list)
|
72
80
|
|
@@ -75,7 +83,7 @@ class ClusterQuery[T]:
|
|
75
83
|
valid_attr: dict[str, Any] = {}
|
76
84
|
for clause in clauses:
|
77
85
|
if not hasattr(table, clause.column):
|
78
|
-
agg_methods = self.
|
86
|
+
agg_methods = self.__get_all_aggregate_method(clauses)
|
79
87
|
raise ValueError(f"You cannot use aggregation method like '{agg_methods}' to return model objects. Try specifying 'flavour' attribute as 'dict'.")
|
80
88
|
valid_attr[clause.column] = dicc_cols[clause.alias]
|
81
89
|
|
@@ -83,7 +91,7 @@ class ClusterQuery[T]:
|
|
83
91
|
table_initialize[table].append(table(**valid_attr))
|
84
92
|
return table_initialize
|
85
93
|
|
86
|
-
def
|
94
|
+
def __get_all_aggregate_method(self, clauses: list[ClauseInfo]) -> str:
|
87
95
|
res: set[str] = set()
|
88
96
|
|
89
97
|
for clause in clauses:
|
@@ -91,12 +99,3 @@ class ClusterQuery[T]:
|
|
91
99
|
if isinstance(row, IAggregate):
|
92
100
|
res.add(row.__class__.__name__)
|
93
101
|
return ", ".join(res)
|
94
|
-
|
95
|
-
def clean_response(self) -> tuple[dict[Type[Table], tuple[Table]]]:
|
96
|
-
tbl_dicc: dict[Type[Table], list[Table]] = self.loop_foo()
|
97
|
-
|
98
|
-
# it not depend of flavour attr
|
99
|
-
for key, val in tbl_dicc.items():
|
100
|
-
tbl_dicc[key] = tuple(val)
|
101
|
-
|
102
|
-
return tuple(tbl_dicc.values())
|
{ormlambda-2.8.0 → ormlambda-2.9.0}/src/ormlambda/common/abstract_classes/decomposition_query.py
RENAMED
@@ -44,6 +44,13 @@ class ClauseInfo[T: tp.Type[Table]]:
|
|
44
44
|
def query(self) -> str:
|
45
45
|
return self._query
|
46
46
|
|
47
|
+
@property
|
48
|
+
def dtype[TProp](self) -> tp.Optional[tp.Type[TProp]]:
|
49
|
+
try:
|
50
|
+
return self._table.get_column(self.column).dtype
|
51
|
+
except ValueError:
|
52
|
+
return None
|
53
|
+
|
47
54
|
def _resolve_column(self, data: ClauseDataType) -> str:
|
48
55
|
if isinstance(data, property):
|
49
56
|
return self._table.__properties_mapped__[data]
|
@@ -73,6 +80,17 @@ class ClauseInfo[T: tp.Type[Table]]:
|
|
73
80
|
|
74
81
|
|
75
82
|
class DecompositionQueryBase[T: tp.Type[Table]](IDecompositionQuery[T]):
|
83
|
+
@tp.overload
|
84
|
+
def __init__[*Ts](self, table: T, lambda_query: tp.Callable[[T], tuple[*Ts]]) -> None: ...
|
85
|
+
@tp.overload
|
86
|
+
def __init__[*Ts](self, table: T, lambda_query: tp.Callable[[T], tuple[*Ts]], *, alias: bool = ...) -> None: ...
|
87
|
+
@tp.overload
|
88
|
+
def __init__[*Ts](self, table: T, lambda_query: tp.Callable[[T], tuple[*Ts]], *, alias: bool = ..., alias_name: tp.Optional[str] = ...) -> None: ...
|
89
|
+
@tp.overload
|
90
|
+
def __init__[*Ts](self, table: T, lambda_query: tp.Callable[[T], tuple[*Ts]], *, alias: bool = ..., alias_name: tp.Optional[str] = ..., by: JoinType = ...) -> None: ...
|
91
|
+
@tp.overload
|
92
|
+
def __init__[*Ts](self, table: T, lambda_query: tp.Callable[[T], tuple[*Ts]], *, alias: bool = ..., alias_name: tp.Optional[str] = ..., by: JoinType = ..., replace_asterisk_char: bool = ...) -> None: ...
|
93
|
+
|
76
94
|
def __init__[*Ts](
|
77
95
|
self,
|
78
96
|
table: T,
|
@@ -98,6 +116,11 @@ class DecompositionQueryBase[T: tp.Type[Table]](IDecompositionQuery[T]):
|
|
98
116
|
|
99
117
|
self.__clauses_list_generetor(lambda_query)
|
100
118
|
|
119
|
+
def __getitem__(self, key: str) -> ClauseInfo:
|
120
|
+
for clause in self._all_clauses:
|
121
|
+
if clause.alias == key:
|
122
|
+
return clause
|
123
|
+
|
101
124
|
def alias_children_resolver[Tclause: tp.Type[Table]](self, clause_info: ClauseInfo[Tclause]):
|
102
125
|
DEFAULT_ALIAS: str = f"{clause_info._table.__table_name__}_{clause_info._column}"
|
103
126
|
|
@@ -2,6 +2,7 @@ from __future__ import annotations
|
|
2
2
|
from typing import Any, Callable, Iterable, Optional, Literal, Type, Union, overload, TYPE_CHECKING, TypeVar
|
3
3
|
from enum import Enum
|
4
4
|
from abc import abstractmethod, ABC
|
5
|
+
import enum
|
5
6
|
|
6
7
|
from .IRepositoryBase import IRepositoryBase
|
7
8
|
from ormlambda.common.enums import JoinType
|
@@ -10,7 +11,15 @@ if TYPE_CHECKING:
|
|
10
11
|
from ormlambda import Table
|
11
12
|
from .IAggregate import IAggregate
|
12
13
|
|
13
|
-
|
14
|
+
|
15
|
+
class OrderType(enum.Enum):
|
16
|
+
ASC = "ASC"
|
17
|
+
DESC = "DESC"
|
18
|
+
|
19
|
+
|
20
|
+
OrderTypeString = Literal["ASC", "DESC"]
|
21
|
+
|
22
|
+
OrderTypes = OrderTypeString | OrderType | Iterable[OrderType]
|
14
23
|
|
15
24
|
# TODOH: This var is duplicated from 'src\ormlambda\databases\my_sql\clauses\create_database.py'
|
16
25
|
TypeExists = Literal["fail", "replace", "append"]
|
@@ -109,7 +118,7 @@ class IStatements[T: Table](ABC):
|
|
109
118
|
@overload
|
110
119
|
def delete(self, instance: list[T]) -> None: ...
|
111
120
|
@abstractmethod
|
112
|
-
def delete(self, instance: Optional[T | list[T]] =
|
121
|
+
def delete(self, instance: Optional[T | list[T]] = ...) -> None: ...
|
113
122
|
|
114
123
|
# endregion
|
115
124
|
# region join
|
@@ -155,9 +164,9 @@ class IStatements[T: Table](ABC):
|
|
155
164
|
@overload
|
156
165
|
def order[TValue](self, _lambda_col: Callable[[T], TValue]) -> IStatements[T]: ...
|
157
166
|
@overload
|
158
|
-
def order[TValue](self, _lambda_col: Callable[[T], TValue], order_type:
|
167
|
+
def order[TValue](self, _lambda_col: Callable[[T], TValue], order_type: OrderTypes) -> IStatements[T]: ...
|
159
168
|
@abstractmethod
|
160
|
-
def order[TValue](self, _lambda_col: Callable[[T], TValue], order_type:
|
169
|
+
def order[TValue](self, _lambda_col: Callable[[T], TValue], order_type: OrderTypes) -> IStatements[T]: ...
|
161
170
|
|
162
171
|
# endregion
|
163
172
|
# region concat
|
@@ -196,62 +205,60 @@ class IStatements[T: Table](ABC):
|
|
196
205
|
@overload
|
197
206
|
def select(self) -> tuple[T, ...]: ...
|
198
207
|
@overload
|
199
|
-
def select[T1](self, selector: Callable[[T], T1], *, by: Optional[Enum] =
|
208
|
+
def select[T1](self, selector: Callable[[T], T1], *, by: Optional[Enum] = ...) -> tuple[tuple[T1, ...]]: ...
|
200
209
|
@overload
|
201
|
-
def select[T1](self, selector: Callable[[T], tuple[T1]], *, by: Optional[Enum] =
|
210
|
+
def select[T1](self, selector: Callable[[T], tuple[T1]], *, by: Optional[Enum] = ...) -> tuple[tuple[T1, ...]]: ...
|
202
211
|
@overload
|
203
|
-
def select[T1, T2](self, selector: Callable[[T], tuple[T1, T2]], *, by: Optional[Enum] =
|
212
|
+
def select[T1, T2](self, selector: Callable[[T], tuple[T1, T2]], *, by: Optional[Enum] = ...) -> tuple[tuple[T1, ...], tuple[T2, ...]]: ...
|
204
213
|
@overload
|
205
|
-
def select[T1, T2, T3](self, selector: Callable[[T], tuple[T1, T2, T3]], *, by: Optional[Enum] =
|
214
|
+
def select[T1, T2, T3](self, selector: Callable[[T], tuple[T1, T2, T3]], *, by: Optional[Enum] = ...) -> tuple[tuple[T1, ...], tuple[T2, ...], tuple[T3, ...]]: ...
|
206
215
|
@overload
|
207
|
-
def select[T1, T2, T3, T4](self, selector: Callable[[T], tuple[T1, T2, T3, T4]], *, by: Optional[Enum] =
|
216
|
+
def select[T1, T2, T3, T4](self, selector: Callable[[T], tuple[T1, T2, T3, T4]], *, by: Optional[Enum] = ...) -> tuple[tuple[T1, ...], tuple[T2, ...], tuple[T3, ...], tuple[T4, ...]]: ...
|
208
217
|
@overload
|
209
|
-
def select[T1, T2, T3, T4, T5](self, selector: Callable[[T], tuple[T1, T2, T3, T4, T5]], *, by: Optional[Enum] =
|
218
|
+
def select[T1, T2, T3, T4, T5](self, selector: Callable[[T], tuple[T1, T2, T3, T4, T5]], *, by: Optional[Enum] = ...) -> tuple[tuple[T1, ...], tuple[T2, ...], tuple[T3, ...], tuple[T4, ...], tuple[T5, ...]]: ...
|
210
219
|
@overload
|
211
|
-
def select[T1, T2, T3, T4, T5, T6](self, selector: Callable[[T], tuple[T1, T2, T3, T4, T5, T6]], *, by: Optional[Enum] =
|
220
|
+
def select[T1, T2, T3, T4, T5, T6](self, selector: Callable[[T], tuple[T1, T2, T3, T4, T5, T6]], *, by: Optional[Enum] = ...) -> tuple[tuple[T1, ...], tuple[T2, ...], tuple[T3, ...], tuple[T4, ...], tuple[T5, ...], tuple[T6, ...]]: ...
|
212
221
|
@overload
|
213
|
-
def select[T1, T2, T3, T4, T5, T6, T7](self, selector: Callable[[T], tuple[T1, T2, T3, T4, T5, T6, T7]], *, by: Optional[Enum] =
|
222
|
+
def select[T1, T2, T3, T4, T5, T6, T7](self, selector: Callable[[T], tuple[T1, T2, T3, T4, T5, T6, T7]], *, by: Optional[Enum] = ...) -> tuple[tuple[T1, ...], tuple[T2, ...], tuple[T3, ...], tuple[T4, ...], tuple[T5, ...], tuple[T6, ...], tuple[T7, ...]]: ...
|
214
223
|
@overload
|
215
|
-
def select[T1, T2, T3, T4, T5, T6, T7, T8](self, selector: Callable[[T], tuple[T1, T2, T3, T4, T5, T6, T7, T8]], *, by: Optional[Enum] =
|
224
|
+
def select[T1, T2, T3, T4, T5, T6, T7, T8](self, selector: Callable[[T], tuple[T1, T2, T3, T4, T5, T6, T7, T8]], *, by: Optional[Enum] = ...) -> tuple[tuple[T1, ...], tuple[T2, ...], tuple[T3, ...], tuple[T4, ...], tuple[T5, ...], tuple[T6, ...], tuple[T7, ...], tuple[T8, ...]]: ...
|
216
225
|
@overload
|
217
|
-
def select[T1, T2, T3, T4, T5, T6, T7, T8, T9](
|
218
|
-
self, selector: Callable[[T], tuple[T1, T2, T3, T4, T5, T6, T7, T8, T9]], *, by: Optional[Enum] = JoinType.INNER_JOIN
|
219
|
-
) -> tuple[tuple[T1, ...], tuple[T2, ...], tuple[T3, ...], tuple[T4, ...], tuple[T5, ...], tuple[T6, ...], tuple[T7, ...], tuple[T8, ...], tuple[T9, ...]]: ...
|
226
|
+
def select[T1, T2, T3, T4, T5, T6, T7, T8, T9](self, selector: Callable[[T], tuple[T1, T2, T3, T4, T5, T6, T7, T8, T9]], *, by: Optional[Enum] = ...) -> tuple[tuple[T1, ...], tuple[T2, ...], tuple[T3, ...], tuple[T4, ...], tuple[T5, ...], tuple[T6, ...], tuple[T7, ...], tuple[T8, ...], tuple[T9, ...]]: ...
|
220
227
|
@overload
|
221
228
|
def select[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10](
|
222
|
-
self, selector: Callable[[T], tuple[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]], *, by: Optional[Enum] =
|
229
|
+
self, selector: Callable[[T], tuple[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]], *, by: Optional[Enum] = ...
|
223
230
|
) -> tuple[tuple[T1, ...], tuple[T2, ...], tuple[T3, ...], tuple[T4, ...], tuple[T5, ...], tuple[T6, ...], tuple[T7, ...], tuple[T8, ...], tuple[T9, ...], tuple[T10, ...]]: ...
|
224
231
|
@overload
|
225
|
-
def select[Ts](self, selector: Optional[Callable[[T], Ts]] =
|
232
|
+
def select[Ts](self, selector: Optional[Callable[[T], Ts]] = ..., *, flavour: Type[tuple], by: Optional[Enum] = ...) -> tuple[Ts, ...]: ...
|
226
233
|
@overload
|
227
|
-
def select[Ts](self, selector: Optional[Callable[[T], tuple[Ts]]] =
|
234
|
+
def select[Ts](self, selector: Optional[Callable[[T], tuple[Ts]]] = ..., *, flavour: Type[tuple], by: Optional[Enum] = ...) -> tuple[Ts, ...]: ...
|
228
235
|
@overload
|
229
|
-
def select[*Ts](self, selector: Optional[Callable[[T], tuple[*Ts]]] =
|
236
|
+
def select[*Ts](self, selector: Optional[Callable[[T], tuple[*Ts]]] = ..., *, flavour: Type[tuple], by: Optional[Enum] = ...) -> tuple[tuple[*Ts]]: ...
|
230
237
|
@overload
|
231
|
-
def select[TFlavour](self, selector: Optional[Callable[[T], tuple]] =
|
238
|
+
def select[TFlavour](self, selector: Optional[Callable[[T], tuple]] = ..., *, flavour: Type[TFlavour], by: Optional[Enum] = ...) -> tuple[TFlavour]: ...
|
232
239
|
@abstractmethod
|
233
|
-
def select[TValue, TFlavour, *Ts](self, selector: Optional[Callable[[T], tuple[TValue, *Ts]]] =
|
240
|
+
def select[TValue, TFlavour, *Ts](self, selector: Optional[Callable[[T], tuple[TValue, *Ts]]] = ..., *, flavour: Type[TFlavour] = ..., by: JoinType = ...): ...
|
234
241
|
|
235
242
|
# endregion
|
236
243
|
# region select_one
|
237
244
|
@overload
|
238
245
|
def select_one(self) -> T: ...
|
239
246
|
@overload
|
240
|
-
def select_one[TFlavour](self, *, by: Optional[Enum] =
|
247
|
+
def select_one[TFlavour](self, *, by: Optional[Enum] = ..., flavour: Type[TFlavour]) -> TFlavour: ...
|
241
248
|
@overload
|
242
|
-
def select_one[T1](self, selector: Callable[[T], tuple[T1]], *, by: Optional[Enum] =
|
249
|
+
def select_one[T1](self, selector: Callable[[T], tuple[T1]], *, by: Optional[Enum] = ...) -> T1: ...
|
243
250
|
@overload
|
244
|
-
def select_one[*Ts](self, selector: Callable[[T], tuple[*Ts]], *, by: Optional[Enum] =
|
251
|
+
def select_one[*Ts](self, selector: Callable[[T], tuple[*Ts]], *, by: Optional[Enum] = ...) -> tuple[*Ts]: ...
|
245
252
|
@overload
|
246
|
-
def select_one[T1](self, selector: Callable[[T], tuple[T1]], *, by: Optional[Enum] =
|
253
|
+
def select_one[T1](self, selector: Callable[[T], tuple[T1]], *, by: Optional[Enum] = ..., flavour: Type) -> T1: ...
|
247
254
|
@overload
|
248
|
-
def select_one[T1, TFlavour](self, selector: Callable[[T], T1], *, by: Optional[Enum] =
|
255
|
+
def select_one[T1, TFlavour](self, selector: Callable[[T], T1], *, by: Optional[Enum] = ..., flavour: Type[TFlavour]) -> T1: ...
|
249
256
|
@overload
|
250
|
-
def select_one[*Ts](self, selector: Callable[[T], tuple[*Ts]], *, by: Optional[Enum] =
|
257
|
+
def select_one[*Ts](self, selector: Callable[[T], tuple[*Ts]], *, by: Optional[Enum] = ..., flavour: Type[tuple]) -> tuple[*Ts]: ...
|
251
258
|
@overload
|
252
|
-
def select_one[TFlavour](self, selector: Callable[[T], tuple], *, by: Optional[Enum] =
|
259
|
+
def select_one[TFlavour](self, selector: Callable[[T], tuple], *, by: Optional[Enum] = ..., flavour: Type[TFlavour]) -> TFlavour: ...
|
253
260
|
@abstractmethod
|
254
|
-
def select_one[TValue, TFlavour, *Ts](self, selector: Optional[Callable[[T], tuple[TValue, *Ts]]] = lambda: None, *, flavour: Type[TFlavour] =
|
261
|
+
def select_one[TValue, TFlavour, *Ts](self, selector: Optional[Callable[[T], tuple[TValue, *Ts]]] = lambda: None, *, flavour: Type[TFlavour] = ..., by: Optional[Enum] = ...): ...
|
255
262
|
|
256
263
|
# endregion
|
257
264
|
# region group_by
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from typing import
|
1
|
+
from typing import override, Iterable
|
2
2
|
from mysql.connector import MySQLConnection
|
3
3
|
|
4
4
|
from ormlambda import Table
|
@@ -24,13 +24,24 @@ class InsertQuery[T: Table](InsertQueryBase[T, IRepositoryBase[MySQLConnection]]
|
|
24
24
|
|
25
25
|
@override
|
26
26
|
def insert(self, instances: T | list[T]) -> None:
|
27
|
-
|
28
|
-
self.__fill_dict_list(
|
29
|
-
cols_tuple = new_dict_list[0].keys()
|
30
|
-
join_cols = ", ".join(cols_tuple)
|
31
|
-
unknown_rows = f'({", ".join(["%s"]*len(cols_tuple))})' # The number of "%s" must match the dict 'dicc_0' length
|
27
|
+
valid_cols: list[list[Column]] = []
|
28
|
+
self.__fill_dict_list(valid_cols, instances)
|
32
29
|
|
33
|
-
|
30
|
+
col_names: list[str] = []
|
31
|
+
wildcards: list[str] = []
|
32
|
+
col_values: list[list[str]] = []
|
33
|
+
for i, cols in enumerate(valid_cols):
|
34
|
+
col_values.append([])
|
35
|
+
for col in cols:
|
36
|
+
if i == 0:
|
37
|
+
col_names.append(col.column_name)
|
38
|
+
wildcards.append(col.placeholder)
|
39
|
+
col_values[-1].append(col.column_value_to_query)
|
40
|
+
|
41
|
+
join_cols = ", ".join(col_names)
|
42
|
+
unknown_rows = f'({", ".join(wildcards)})' # The number of "%s" must match the dict 'dicc_0' length
|
43
|
+
|
44
|
+
self._values = [tuple(x) for x in col_values]
|
34
45
|
self._query = f"{self.CLAUSE} {self._model.__table_name__} {f'({join_cols})'} VALUES {unknown_rows}"
|
35
46
|
return None
|
36
47
|
|
@@ -55,17 +66,18 @@ class InsertQuery[T: Table](InsertQueryBase[T, IRepositoryBase[MySQLConnection]]
|
|
55
66
|
return False
|
56
67
|
return True
|
57
68
|
|
58
|
-
def __fill_dict_list(self, list_dict: list[
|
69
|
+
def __fill_dict_list[TProp](self, list_dict: list[str, TProp], values: T | list[T]) -> list[Column]:
|
59
70
|
if issubclass(values.__class__, Table):
|
60
|
-
|
71
|
+
new_list = []
|
61
72
|
for col in values.__dict__.values():
|
62
73
|
if isinstance(col, Column) and self.__is_valid(col):
|
63
|
-
|
64
|
-
|
65
|
-
|
74
|
+
new_list.append(col)
|
75
|
+
|
76
|
+
list_dict.append(new_list)
|
66
77
|
|
67
78
|
elif isinstance(values, Iterable):
|
68
79
|
for x in values:
|
69
80
|
self.__fill_dict_list(list_dict, x)
|
70
81
|
else:
|
71
82
|
raise Exception(f"Tipo de dato'{type(values)}' no esperado")
|
83
|
+
return None
|
@@ -0,0 +1,47 @@
|
|
1
|
+
from __future__ import annotations
|
2
|
+
from typing import override, Callable, TYPE_CHECKING, Any, Iterable
|
3
|
+
|
4
|
+
from ormlambda.common.abstract_classes.decomposition_query import ClauseInfo
|
5
|
+
|
6
|
+
|
7
|
+
if TYPE_CHECKING:
|
8
|
+
from ormlambda import Table
|
9
|
+
|
10
|
+
from ormlambda.common.abstract_classes.decomposition_query import DecompositionQueryBase
|
11
|
+
from ormlambda.common.interfaces.IStatements import OrderType
|
12
|
+
|
13
|
+
|
14
|
+
class OrderQuery[T: Table](DecompositionQueryBase[T]):
|
15
|
+
ORDER = "ORDER BY"
|
16
|
+
|
17
|
+
def __init__[*Ts](self, instance: T, lambda_query: Callable[[Any], tuple[*Ts]], order_type: Iterable[OrderType]) -> None:
|
18
|
+
super().__init__(instance, lambda_query)
|
19
|
+
|
20
|
+
if isinstance(order_type, str) or not isinstance(order_type, Iterable):
|
21
|
+
order_type = (order_type,)
|
22
|
+
|
23
|
+
self._order_type: list[OrderType] = [self.__cast_to_OrderType(x) for x in order_type]
|
24
|
+
|
25
|
+
def __cast_to_OrderType(self, _value: Any) -> Iterable[OrderType]:
|
26
|
+
if isinstance(_value, OrderType):
|
27
|
+
return _value
|
28
|
+
|
29
|
+
if isinstance(_value, str):
|
30
|
+
try:
|
31
|
+
return OrderType(_value)
|
32
|
+
except Exception:
|
33
|
+
pass
|
34
|
+
raise Exception(f"order_type param only can be 'ASC' or 'DESC' string or '{OrderType.__name__}' enum")
|
35
|
+
|
36
|
+
def alias_children_resolver[Tclause](self, clause_info: ClauseInfo[Tclause]):
|
37
|
+
return None
|
38
|
+
|
39
|
+
@override
|
40
|
+
@property
|
41
|
+
def query(self) -> str:
|
42
|
+
assert len(self.all_clauses) == len(self._order_type)
|
43
|
+
|
44
|
+
query: list[str] = []
|
45
|
+
for index, x in enumerate(self.all_clauses):
|
46
|
+
query.append(f"{x.query} {self._order_type[index].value}")
|
47
|
+
return f"{self.ORDER} {", ".join(query)}"
|
@@ -3,6 +3,7 @@ from typing import override, Type, Callable, TYPE_CHECKING
|
|
3
3
|
from ormlambda.common.abstract_classes.decomposition_query import DecompositionQueryBase
|
4
4
|
from ormlambda.common.enums.join_type import JoinType
|
5
5
|
from ormlambda.common.interfaces.IAggregate import IAggregate
|
6
|
+
import shapely as shp
|
6
7
|
|
7
8
|
if TYPE_CHECKING:
|
8
9
|
from ormlambda import Table
|
@@ -32,17 +33,20 @@ class Select[T: Type[Table]](DecompositionQueryBase[T]):
|
|
32
33
|
# def alias_children_resolver[Tclause: Type[Table]](self, clause_info: ClauseInfo[Tclause]):
|
33
34
|
# return f"{clause.table.__table_name__}_{name}"
|
34
35
|
|
36
|
+
# TODOL: see who to deal when we will have to add more mysql methods
|
35
37
|
@override
|
36
38
|
@property
|
37
39
|
def query(self) -> str:
|
38
|
-
cols:list[str] = []
|
40
|
+
cols: list[str] = []
|
39
41
|
for x in self.all_clauses:
|
40
|
-
|
42
|
+
if x.dtype is shp.Point:
|
43
|
+
cols.append(x.concat_with_alias(f"ST_AsText({self._table.__table_name__}.{x.column})"))
|
44
|
+
else:
|
45
|
+
cols.append(x.query)
|
41
46
|
|
42
|
-
if isinstance(x._row_column,IAggregate) and x._row_column.has_foreign_keys:
|
47
|
+
if isinstance(x._row_column, IAggregate) and x._row_column.has_foreign_keys:
|
43
48
|
self._fk_relationship.update(x._row_column.fk_relationship)
|
44
49
|
|
45
|
-
|
46
50
|
col: str = ", ".join(cols)
|
47
51
|
query: str = f"{self.CLAUSE} {col} FROM {self._table.__table_name__}"
|
48
52
|
alias = ""
|
@@ -27,26 +27,20 @@ class UpdateQuery[T: Type[Table]](UpdateQueryBase[T, IRepositoryBase[MySQLConnec
|
|
27
27
|
if not isinstance(dicc, dict):
|
28
28
|
raise TypeError
|
29
29
|
|
30
|
-
name_cols: list[
|
30
|
+
name_cols: list[Column] = []
|
31
31
|
|
32
32
|
for col, value in dicc.items():
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
name_cols.append(string_col)
|
41
|
-
self._values.append(value)
|
42
|
-
|
43
|
-
set_query: str = ",".join(["=".join([col, "%s"]) for col in name_cols])
|
33
|
+
col: Column = self._model.get_column(col, value)
|
34
|
+
|
35
|
+
if self.__is_valid__(col):
|
36
|
+
name_cols.append(col)
|
37
|
+
self._values.append(col.column_value_to_query)
|
38
|
+
|
39
|
+
set_query: str = ",".join(["=".join([col.column_name, col.placeholder]) for col in name_cols])
|
44
40
|
|
45
41
|
self._query = f"{self.CLAUSE} {self._model.__table_name__} SET {set_query}"
|
42
|
+
self._values = tuple(self._values)
|
46
43
|
return None
|
47
44
|
|
48
|
-
def __is_valid__(self, col:
|
49
|
-
|
50
|
-
|
51
|
-
column: Column = getattr(instance_table, f"_{col}")
|
52
|
-
return not column.is_auto_generated
|
45
|
+
def __is_valid__(self, col: Column) -> bool:
|
46
|
+
return not col.is_auto_generated
|
@@ -1,7 +1,8 @@
|
|
1
1
|
from __future__ import annotations
|
2
2
|
from pathlib import Path
|
3
|
-
from typing import Any, Optional, Type, override, Callable
|
3
|
+
from typing import Any, Optional, Type, override, Callable, TYPE_CHECKING
|
4
4
|
import functools
|
5
|
+
import shapely as shp
|
5
6
|
|
6
7
|
# from mysql.connector.pooling import MySQLConnectionPool
|
7
8
|
from mysql.connector import MySQLConnection, Error # noqa: F401
|
@@ -16,12 +17,20 @@ from .clauses import DropDatabase
|
|
16
17
|
from .clauses import DropTable
|
17
18
|
|
18
19
|
|
20
|
+
if TYPE_CHECKING:
|
21
|
+
from src.ormlambda.common.abstract_classes.decomposition_query import ClauseInfo
|
22
|
+
from ormlambda import Table
|
23
|
+
from src.ormlambda.databases.my_sql.clauses.select import Select
|
24
|
+
|
25
|
+
|
19
26
|
class Response[TFlavour, *Ts]:
|
20
|
-
def __init__(self, response_values: list[tuple[*Ts]], columns: tuple[str], flavour: Type[TFlavour], **kwargs) -> None:
|
27
|
+
def __init__(self, response_values: list[tuple[*Ts]], columns: tuple[str], flavour: Type[TFlavour], model: Optional[Table] = None, select: Optional[Select] = None, **kwargs) -> None:
|
21
28
|
self._response_values: list[tuple[*Ts]] = response_values
|
22
29
|
self._columns: tuple[str] = columns
|
23
30
|
self._flavour: Type[TFlavour] = flavour
|
24
31
|
self._kwargs: dict[str, Any] = kwargs
|
32
|
+
self._model: Table = model
|
33
|
+
self._select: Select = select
|
25
34
|
|
26
35
|
self._response_values_index: int = len(self._response_values)
|
27
36
|
# self.select_values()
|
@@ -42,8 +51,10 @@ class Response[TFlavour, *Ts]:
|
|
42
51
|
def response(self) -> tuple[dict[str, tuple[*Ts]]] | tuple[tuple[*Ts]] | tuple[TFlavour]:
|
43
52
|
if not self.is_there_response:
|
44
53
|
return tuple([])
|
45
|
-
|
46
|
-
|
54
|
+
clean_response = self._response_values
|
55
|
+
if self._select is not None:
|
56
|
+
clean_response = self._parser_response()
|
57
|
+
return tuple(self._cast_to_flavour(clean_response))
|
47
58
|
|
48
59
|
def _cast_to_flavour(self, data: list[tuple[*Ts]]) -> list[dict[str, tuple[*Ts]]] | list[tuple[*Ts]] | list[TFlavour]:
|
49
60
|
def _dict() -> list[dict[str, tuple[*Ts]]]:
|
@@ -73,6 +84,38 @@ class Response[TFlavour, *Ts]:
|
|
73
84
|
|
74
85
|
return selector.get(self._flavour, _default)()
|
75
86
|
|
87
|
+
def _parser_response(self) -> TFlavour:
|
88
|
+
new_response: list[list] = []
|
89
|
+
for row in self._response_values:
|
90
|
+
new_row: list = []
|
91
|
+
for i, data in enumerate(row):
|
92
|
+
alias = self._columns[i]
|
93
|
+
clause_info = self._select[alias]
|
94
|
+
if not self._is_parser_required(clause_info):
|
95
|
+
new_row = row
|
96
|
+
break
|
97
|
+
else:
|
98
|
+
parser_data = self.parser_data(clause_info, data)
|
99
|
+
new_row.append(parser_data)
|
100
|
+
if not isinstance(new_row, tuple):
|
101
|
+
new_row = tuple(new_row)
|
102
|
+
|
103
|
+
new_response.append(new_row)
|
104
|
+
return new_response
|
105
|
+
|
106
|
+
@staticmethod
|
107
|
+
def _is_parser_required[T: Table](clause_info: ClauseInfo[T]) -> bool:
|
108
|
+
if clause_info is None:
|
109
|
+
return False
|
110
|
+
|
111
|
+
return clause_info.dtype is shp.Point
|
112
|
+
|
113
|
+
@staticmethod
|
114
|
+
def parser_data[T: Table, TProp](clause_info: ClauseInfo[T], data: TProp):
|
115
|
+
if clause_info.dtype is shp.Point:
|
116
|
+
return shp.from_wkt(data)
|
117
|
+
return data
|
118
|
+
|
76
119
|
|
77
120
|
class MySQLRepository(IRepositoryBase[MySQLConnection]):
|
78
121
|
def get_connection(func: Callable[..., Any]):
|
@@ -107,11 +150,19 @@ class MySQLRepository(IRepositoryBase[MySQLConnection]):
|
|
107
150
|
- flavour: Type[TFlavour]: Useful to return tuple of any Iterable type as dict,set,list...
|
108
151
|
"""
|
109
152
|
|
153
|
+
def get_and_drop_key(key: str) -> Optional[Any]:
|
154
|
+
if key in kwargs:
|
155
|
+
return kwargs.pop(key)
|
156
|
+
return None
|
157
|
+
|
158
|
+
model: Table = get_and_drop_key("model")
|
159
|
+
select: Select = get_and_drop_key("select")
|
160
|
+
|
110
161
|
with cnx.cursor(buffered=True) as cursor:
|
111
162
|
cursor.execute(query)
|
112
163
|
values: list[tuple] = cursor.fetchall()
|
113
164
|
columns: tuple[str] = cursor.column_names
|
114
|
-
return Response[TFlavour](response_values=values, columns=columns, flavour=flavour, **kwargs).response
|
165
|
+
return Response[TFlavour](model=model, response_values=values, columns=columns, flavour=flavour, select=select, **kwargs).response
|
115
166
|
|
116
167
|
# FIXME [ ]: this method does not comply with the implemented interface
|
117
168
|
@get_connection
|
@@ -192,7 +243,6 @@ class MySQLRepository(IRepositoryBase[MySQLConnection]):
|
|
192
243
|
def create_database(self, name: str, if_exists: TypeExists = "fail") -> None:
|
193
244
|
return CreateDatabase(self).execute(name, if_exists)
|
194
245
|
|
195
|
-
|
196
246
|
@property
|
197
247
|
def database(self) -> Optional[str]:
|
198
248
|
return self._data_config.get("database", None)
|