ormlambda 2.6.1__py3-none-any.whl → 2.8.0__py3-none-any.whl
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/common/abstract_classes/abstract_model.py +1 -1
- ormlambda/common/abstract_classes/decomposition_query.py +0 -1
- ormlambda/common/interfaces/IDecompositionQuery.py +1 -1
- ormlambda/common/interfaces/IRepositoryBase.py +0 -4
- ormlambda/common/interfaces/IStatements.py +46 -27
- ormlambda/databases/my_sql/clauses/__init__.py +1 -1
- ormlambda/databases/my_sql/{functions → clauses}/group_by.py +0 -2
- ormlambda/databases/my_sql/clauses/order.py +6 -2
- ormlambda/databases/my_sql/clauses/select.py +10 -1
- ormlambda/databases/my_sql/functions/__init__.py +5 -3
- ormlambda/databases/my_sql/functions/min.py +39 -0
- ormlambda/databases/my_sql/functions/sum.py +39 -0
- ormlambda/databases/my_sql/repository.py +2 -6
- ormlambda/databases/my_sql/statements.py +87 -30
- {ormlambda-2.6.1.dist-info → ormlambda-2.8.0.dist-info}/METADATA +1 -1
- {ormlambda-2.6.1.dist-info → ormlambda-2.8.0.dist-info}/RECORD +18 -16
- {ormlambda-2.6.1.dist-info → ormlambda-2.8.0.dist-info}/LICENSE +0 -0
- {ormlambda-2.6.1.dist-info → ormlambda-2.8.0.dist-info}/WHEEL +0 -0
@@ -76,7 +76,7 @@ class ClusterQuery[T]:
|
|
76
76
|
for clause in clauses:
|
77
77
|
if not hasattr(table, clause.column):
|
78
78
|
agg_methods = self.get_all_aggregate_method(clauses)
|
79
|
-
raise ValueError(f"You cannot use aggregation method like '{agg_methods}' to return model objects")
|
79
|
+
raise ValueError(f"You cannot use aggregation method like '{agg_methods}' to return model objects. Try specifying 'flavour' attribute as 'dict'.")
|
80
80
|
valid_attr[clause.column] = dicc_cols[clause.alias]
|
81
81
|
|
82
82
|
# COMMENT: At this point we are going to instantiate Table class with specific attributes getting directly from database
|
@@ -28,7 +28,6 @@ class ClauseInfo[T: tp.Type[Table]]:
|
|
28
28
|
self._alias: tp.Optional[str] = self._alias_children_resolver(self)
|
29
29
|
|
30
30
|
self._query: str = self.__create_value_string(self._column)
|
31
|
-
pass
|
32
31
|
|
33
32
|
def __repr__(self) -> str:
|
34
33
|
return f"{ClauseInfo.__name__}: {self.query}"
|
@@ -31,7 +31,7 @@ class IDecompositionQuery[T: tp.Type[Table]](IQuery):
|
|
31
31
|
|
32
32
|
@property
|
33
33
|
@abc.abstractmethod
|
34
|
-
def fk_relationship(self) ->
|
34
|
+
def fk_relationship(self) -> set[tuple[tp.Type[Table], tp.Type[Table]]]: ...
|
35
35
|
|
36
36
|
@property
|
37
37
|
@abc.abstractmethod
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from __future__ import annotations
|
2
|
-
from typing import Any, Callable, Iterable, Optional, Literal, Type, overload, TYPE_CHECKING
|
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
5
|
|
@@ -8,12 +8,16 @@ from ormlambda.common.enums import JoinType
|
|
8
8
|
|
9
9
|
if TYPE_CHECKING:
|
10
10
|
from ormlambda import Table
|
11
|
+
from .IAggregate import IAggregate
|
11
12
|
|
12
13
|
OrderType = Literal["ASC", "DESC"]
|
13
14
|
|
14
15
|
# TODOH: This var is duplicated from 'src\ormlambda\databases\my_sql\clauses\create_database.py'
|
15
16
|
TypeExists = Literal["fail", "replace", "append"]
|
16
17
|
|
18
|
+
T = TypeVar("T")
|
19
|
+
WhereTypes = Union[Callable[[T], bool], Iterable[Callable[[T], bool]]]
|
20
|
+
|
17
21
|
|
18
22
|
class IStatements[T: Table](ABC):
|
19
23
|
@abstractmethod
|
@@ -45,7 +49,6 @@ class IStatements[T: Table](ABC):
|
|
45
49
|
def insert(self, values: T | list[T]) -> None: ...
|
46
50
|
|
47
51
|
# endregion
|
48
|
-
|
49
52
|
# region upsert
|
50
53
|
@overload
|
51
54
|
def upsert(self, values: T) -> None:
|
@@ -76,25 +79,26 @@ class IStatements[T: Table](ABC):
|
|
76
79
|
def update(self, dicc: dict[str | property, Any]) -> None: ...
|
77
80
|
|
78
81
|
# endregion
|
79
|
-
|
80
82
|
# region limit
|
81
83
|
@abstractmethod
|
82
84
|
def limit(self, number: int) -> IStatements[T]: ...
|
83
85
|
|
84
86
|
# endregion
|
85
|
-
|
86
87
|
# region offset
|
87
88
|
@abstractmethod
|
88
89
|
def offset(self, number: int) -> IStatements[T]: ...
|
89
90
|
|
90
91
|
# endregion
|
91
|
-
|
92
92
|
# region count
|
93
93
|
@abstractmethod
|
94
|
-
def count(
|
94
|
+
def count(
|
95
|
+
self,
|
96
|
+
selection: Callable[[T], property],
|
97
|
+
alias: bool = ...,
|
98
|
+
alias_name: Optional[str] = ...,
|
99
|
+
) -> int: ...
|
95
100
|
|
96
101
|
# endregion
|
97
|
-
|
98
102
|
# region delete
|
99
103
|
@overload
|
100
104
|
def delete(self) -> None: ...
|
@@ -108,28 +112,15 @@ class IStatements[T: Table](ABC):
|
|
108
112
|
def delete(self, instance: Optional[T | list[T]] = None) -> None: ...
|
109
113
|
|
110
114
|
# endregion
|
111
|
-
|
112
115
|
# region join
|
113
116
|
@abstractmethod
|
114
117
|
def join(self, table_left: Table, table_right: Table, *, by: str) -> IStatements[T]: ...
|
115
118
|
|
116
119
|
# endregion
|
117
|
-
|
118
120
|
# region where
|
119
|
-
@overload
|
120
|
-
def where(self, lambda_: Callable[[T], bool]) -> IStatements[T]:
|
121
|
-
"""
|
122
|
-
This method creates where clause by passing the lambda's condition
|
123
|
-
|
124
|
-
EXAMPLE
|
125
|
-
-
|
126
|
-
mb = BaseModel()
|
127
|
-
mb.where(lambda a: 10 <= a.city_id <= 100)
|
128
|
-
"""
|
129
|
-
...
|
130
121
|
|
131
122
|
@overload
|
132
|
-
def where(self,
|
123
|
+
def where(self, conditions: Iterable[Callable[[T], bool]]) -> IStatements[T]:
|
133
124
|
"""
|
134
125
|
This method creates where clause by passing the Iterable in lambda function
|
135
126
|
EXAMPLE
|
@@ -140,7 +131,7 @@ class IStatements[T: Table](ABC):
|
|
140
131
|
...
|
141
132
|
|
142
133
|
@overload
|
143
|
-
def where(self,
|
134
|
+
def where(self, conditions: Callable[[T], bool], **kwargs) -> IStatements[T]:
|
144
135
|
"""
|
145
136
|
PARAM
|
146
137
|
-
|
@@ -157,10 +148,9 @@ class IStatements[T: Table](ABC):
|
|
157
148
|
...
|
158
149
|
|
159
150
|
@abstractmethod
|
160
|
-
def where(self,
|
151
|
+
def where(self, conditions: WhereTypes = lambda: None, **kwargs) -> IStatements[T]: ...
|
161
152
|
|
162
153
|
# endregion
|
163
|
-
|
164
154
|
# region order
|
165
155
|
@overload
|
166
156
|
def order[TValue](self, _lambda_col: Callable[[T], TValue]) -> IStatements[T]: ...
|
@@ -170,7 +160,38 @@ class IStatements[T: Table](ABC):
|
|
170
160
|
def order[TValue](self, _lambda_col: Callable[[T], TValue], order_type: OrderType) -> IStatements[T]: ...
|
171
161
|
|
172
162
|
# endregion
|
163
|
+
# region concat
|
164
|
+
@overload
|
165
|
+
def concat[*Ts](self, selector: Callable[[T], tuple[*Ts]]) -> IAggregate[T]: ...
|
173
166
|
|
167
|
+
# endregion
|
168
|
+
# region max
|
169
|
+
@overload
|
170
|
+
def max[TProp](
|
171
|
+
self,
|
172
|
+
column: Callable[[T], TProp],
|
173
|
+
alias: bool = ...,
|
174
|
+
alias_name: Optional[str] = ...,
|
175
|
+
) -> TProp: ...
|
176
|
+
# endregion
|
177
|
+
# region min
|
178
|
+
@overload
|
179
|
+
def min[TProp](
|
180
|
+
self,
|
181
|
+
column: Callable[[T], TProp],
|
182
|
+
alias: bool = ...,
|
183
|
+
alias_name: Optional[str] = ...,
|
184
|
+
) -> TProp: ...
|
185
|
+
# endregion
|
186
|
+
# region sum
|
187
|
+
@overload
|
188
|
+
def sum[TProp](
|
189
|
+
self,
|
190
|
+
column: Callable[[T], TProp],
|
191
|
+
alias: bool = ...,
|
192
|
+
alias_name: Optional[str] = ...,
|
193
|
+
) -> TProp: ...
|
194
|
+
# endregion
|
174
195
|
# region select
|
175
196
|
@overload
|
176
197
|
def select(self) -> tuple[T, ...]: ...
|
@@ -212,7 +233,6 @@ class IStatements[T: Table](ABC):
|
|
212
233
|
def select[TValue, TFlavour, *Ts](self, selector: Optional[Callable[[T], tuple[TValue, *Ts]]] = lambda: None, *, flavour: Type[TFlavour] = None, by: JoinType = JoinType.INNER_JOIN): ...
|
213
234
|
|
214
235
|
# endregion
|
215
|
-
|
216
236
|
# region select_one
|
217
237
|
@overload
|
218
238
|
def select_one(self) -> T: ...
|
@@ -234,10 +254,9 @@ class IStatements[T: Table](ABC):
|
|
234
254
|
def select_one[TValue, TFlavour, *Ts](self, selector: Optional[Callable[[T], tuple[TValue, *Ts]]] = lambda: None, *, flavour: Type[TFlavour] = None, by: Optional[Enum] = JoinType.INNER_JOIN): ...
|
235
255
|
|
236
256
|
# endregion
|
237
|
-
|
238
257
|
# region group_by
|
239
258
|
@abstractmethod
|
240
|
-
def group_by[TRepo, *Ts](self, column: Callable[[T], TRepo]
|
259
|
+
def group_by[TRepo, *Ts](self, column: Callable[[T], TRepo]) -> IStatements[T]: ...
|
241
260
|
|
242
261
|
# endregion
|
243
262
|
|
@@ -13,4 +13,4 @@ from .update import UpdateQuery as UpdateQuery
|
|
13
13
|
from .upsert import UpsertQuery as UpsertQuery
|
14
14
|
from .where_condition import WhereCondition as WhereCondition
|
15
15
|
from .count import Count as Count
|
16
|
-
from
|
16
|
+
from .group_by import GroupBy as GroupBy
|
@@ -1,4 +1,8 @@
|
|
1
|
-
from
|
1
|
+
from __future__ import annotations
|
2
|
+
from typing import override, Callable, TYPE_CHECKING
|
3
|
+
|
4
|
+
if TYPE_CHECKING:
|
5
|
+
from ormlambda import Table
|
2
6
|
|
3
7
|
from ormlambda.utils.lambda_disassembler.tree_instruction import TreeInstruction
|
4
8
|
from ormlambda.common.interfaces.IQueryCommand import IQuery
|
@@ -8,7 +12,7 @@ ASC = "ASC"
|
|
8
12
|
DESC = "DESC"
|
9
13
|
|
10
14
|
|
11
|
-
class OrderQuery[T](IQuery):
|
15
|
+
class OrderQuery[T:Table](IQuery):
|
12
16
|
ORDER = "ORDER BY"
|
13
17
|
|
14
18
|
def __init__(self, instance: T, order_lambda: Callable[[T], None], order_type: OrderType) -> None:
|
@@ -2,6 +2,7 @@ from typing import override, Type, Callable, TYPE_CHECKING
|
|
2
2
|
|
3
3
|
from ormlambda.common.abstract_classes.decomposition_query import DecompositionQueryBase
|
4
4
|
from ormlambda.common.enums.join_type import JoinType
|
5
|
+
from ormlambda.common.interfaces.IAggregate import IAggregate
|
5
6
|
|
6
7
|
if TYPE_CHECKING:
|
7
8
|
from ormlambda import Table
|
@@ -34,7 +35,15 @@ class Select[T: Type[Table]](DecompositionQueryBase[T]):
|
|
34
35
|
@override
|
35
36
|
@property
|
36
37
|
def query(self) -> str:
|
37
|
-
|
38
|
+
cols:list[str] = []
|
39
|
+
for x in self.all_clauses:
|
40
|
+
cols.append(x.query)
|
41
|
+
|
42
|
+
if isinstance(x._row_column,IAggregate) and x._row_column.has_foreign_keys:
|
43
|
+
self._fk_relationship.update(x._row_column.fk_relationship)
|
44
|
+
|
45
|
+
|
46
|
+
col: str = ", ".join(cols)
|
38
47
|
query: str = f"{self.CLAUSE} {col} FROM {self._table.__table_name__}"
|
39
48
|
alias = ""
|
40
49
|
|
@@ -1,3 +1,5 @@
|
|
1
|
-
from .max import Max
|
2
|
-
from .
|
3
|
-
from .
|
1
|
+
from .max import Max as Max
|
2
|
+
from .min import Min as Min
|
3
|
+
from .concat import Concat as Concat
|
4
|
+
from ..clauses.group_by import GroupBy as GroupBy
|
5
|
+
from .sum import Sum as Sum
|
@@ -0,0 +1,39 @@
|
|
1
|
+
from ormlambda.common.interfaces import IAggregate
|
2
|
+
import typing as tp
|
3
|
+
|
4
|
+
from ormlambda.common.abstract_classes.decomposition_query import DecompositionQueryBase, ClauseInfo
|
5
|
+
|
6
|
+
if tp.TYPE_CHECKING:
|
7
|
+
from ormlambda import Table
|
8
|
+
|
9
|
+
|
10
|
+
class Min[T: tp.Type[Table]](DecompositionQueryBase[T], IAggregate[T]):
|
11
|
+
NAME: str = "MIN"
|
12
|
+
|
13
|
+
@tp.overload
|
14
|
+
def __init__[T: tp.Type[Table]](self, table: T, column: tp.Callable[[T], tp.Any], *, alias: bool = True, alias_name: str = "min") -> None: ...
|
15
|
+
|
16
|
+
def __init__(
|
17
|
+
self,
|
18
|
+
table: T,
|
19
|
+
column: str | tp.Callable[[T], tuple],
|
20
|
+
*,
|
21
|
+
alias: bool = True,
|
22
|
+
alias_name: str = "min",
|
23
|
+
) -> None:
|
24
|
+
super().__init__(
|
25
|
+
table,
|
26
|
+
lambda_query=column,
|
27
|
+
alias=alias,
|
28
|
+
alias_name=alias_name,
|
29
|
+
)
|
30
|
+
|
31
|
+
def alias_children_resolver[Tclause: tp.Type[Table]](self, clause_info: ClauseInfo[Tclause]):
|
32
|
+
if isinstance(clause_info._row_column, IAggregate):
|
33
|
+
return clause_info._row_column.alias
|
34
|
+
return None
|
35
|
+
|
36
|
+
@property
|
37
|
+
def query(self) -> str:
|
38
|
+
col = ", ".join([x.query for x in self.all_clauses])
|
39
|
+
return f"{self.NAME}({col})"
|
@@ -0,0 +1,39 @@
|
|
1
|
+
from ormlambda.common.interfaces import IAggregate
|
2
|
+
import typing as tp
|
3
|
+
|
4
|
+
from ormlambda.common.abstract_classes.decomposition_query import DecompositionQueryBase, ClauseInfo
|
5
|
+
|
6
|
+
if tp.TYPE_CHECKING:
|
7
|
+
from ormlambda import Table
|
8
|
+
|
9
|
+
|
10
|
+
class Sum[T: tp.Type[Table]](DecompositionQueryBase[T], IAggregate[T]):
|
11
|
+
NAME: str = "SUM"
|
12
|
+
|
13
|
+
@tp.overload
|
14
|
+
def __init__[T: tp.Type[Table]](self, table: T, column: tp.Callable[[T], tp.Any], *, alias: bool = True, alias_name: str = ...) -> None: ...
|
15
|
+
|
16
|
+
def __init__(
|
17
|
+
self,
|
18
|
+
table: T,
|
19
|
+
column: str | tp.Callable[[T], tuple],
|
20
|
+
*,
|
21
|
+
alias: bool = True,
|
22
|
+
alias_name: str = "sum",
|
23
|
+
) -> None:
|
24
|
+
super().__init__(
|
25
|
+
table,
|
26
|
+
lambda_query=column,
|
27
|
+
alias=alias,
|
28
|
+
alias_name=alias_name,
|
29
|
+
)
|
30
|
+
|
31
|
+
def alias_children_resolver[Tclause: tp.Type[Table]](self, clause_info: ClauseInfo[Tclause]):
|
32
|
+
if isinstance(clause_info._row_column, IAggregate):
|
33
|
+
return clause_info._row_column.alias
|
34
|
+
return None
|
35
|
+
|
36
|
+
@property
|
37
|
+
def query(self) -> str:
|
38
|
+
col = ", ".join([x.query for x in self.all_clauses])
|
39
|
+
return f"{self.NAME}({col})"
|
@@ -80,10 +80,10 @@ class MySQLRepository(IRepositoryBase[MySQLConnection]):
|
|
80
80
|
def wrapper(self: MySQLRepository, *args, **kwargs):
|
81
81
|
with self._pool.get_connection() as cnx:
|
82
82
|
try:
|
83
|
-
foo = func(self, cnx, *args, **kwargs)
|
83
|
+
foo = func(self, cnx._cnx, *args, **kwargs)
|
84
84
|
return foo
|
85
85
|
except Exception as e:
|
86
|
-
|
86
|
+
cnx._cnx.rollback()
|
87
87
|
raise e
|
88
88
|
|
89
89
|
return wrapper
|
@@ -192,10 +192,6 @@ class MySQLRepository(IRepositoryBase[MySQLConnection]):
|
|
192
192
|
def create_database(self, name: str, if_exists: TypeExists = "fail") -> None:
|
193
193
|
return CreateDatabase(self).execute(name, if_exists)
|
194
194
|
|
195
|
-
@override
|
196
|
-
@property
|
197
|
-
def connection(self) -> MySQLConnection:
|
198
|
-
return self._connection
|
199
195
|
|
200
196
|
@property
|
201
197
|
def database(self) -> Optional[str]:
|
@@ -1,5 +1,8 @@
|
|
1
1
|
from __future__ import annotations
|
2
|
-
from typing import override, Type, TYPE_CHECKING, Any, Callable, Optional
|
2
|
+
from typing import Iterable, override, Type, TYPE_CHECKING, Any, Callable, Optional
|
3
|
+
import inspect
|
4
|
+
from mysql.connector import MySQLConnection, errors, errorcode
|
5
|
+
|
3
6
|
|
4
7
|
if TYPE_CHECKING:
|
5
8
|
from ormlambda import Table
|
@@ -7,6 +10,8 @@ if TYPE_CHECKING:
|
|
7
10
|
from ormlambda.common.interfaces.IStatements import OrderType
|
8
11
|
from ormlambda.common.interfaces import IQuery, IRepositoryBase, IStatements_two_generic
|
9
12
|
from ormlambda.common.interfaces.IRepositoryBase import TypeExists
|
13
|
+
from ormlambda.common.interfaces import IAggregate
|
14
|
+
from ormlambda.common.interfaces.IStatements import WhereTypes
|
10
15
|
|
11
16
|
from ormlambda import AbstractSQLStatements
|
12
17
|
from .clauses import DeleteQuery
|
@@ -23,13 +28,10 @@ from .clauses import WhereCondition
|
|
23
28
|
from .clauses import Count
|
24
29
|
from .clauses import GroupBy
|
25
30
|
|
26
|
-
from mysql.connector import MySQLConnection, errors, errorcode
|
27
|
-
|
28
|
-
|
29
|
-
import inspect
|
30
31
|
|
31
32
|
from ormlambda.utils import ForeignKey, Table
|
32
33
|
from ormlambda.common.enums import JoinType
|
34
|
+
from . import functions as func
|
33
35
|
|
34
36
|
|
35
37
|
class MySQLStatements[T: Table](AbstractSQLStatements[T, MySQLConnection]):
|
@@ -126,11 +128,13 @@ class MySQLStatements[T: Table](AbstractSQLStatements[T, MySQLConnection]):
|
|
126
128
|
return self
|
127
129
|
|
128
130
|
@override
|
129
|
-
def count(
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
131
|
+
def count(
|
132
|
+
self,
|
133
|
+
selection: Callable[[T], tuple] = lambda x: "*",
|
134
|
+
alias=True,
|
135
|
+
alias_name=None,
|
136
|
+
) -> IQuery:
|
137
|
+
return Count[T](self._model, selection, alias=alias, alias_name=alias_name)
|
134
138
|
|
135
139
|
@override
|
136
140
|
def join(self, table_left: Table, table_right: Table, *, by: str) -> IStatements_two_generic[T, MySQLConnection]:
|
@@ -140,9 +144,15 @@ class MySQLStatements[T: Table](AbstractSQLStatements[T, MySQLConnection]):
|
|
140
144
|
return self
|
141
145
|
|
142
146
|
@override
|
143
|
-
def where(self,
|
147
|
+
def where(self, conditions: WhereTypes = lambda: None, **kwargs) -> IStatements_two_generic[T, MySQLConnection]:
|
144
148
|
# FIXME [x]: I've wrapped self._model into tuple to pass it instance attr. Idk if it's correct
|
145
|
-
|
149
|
+
|
150
|
+
if isinstance(conditions, Iterable):
|
151
|
+
for x in conditions:
|
152
|
+
self._query_list["where"].append(WhereCondition[T](function=x, instances=(self._model,), **kwargs))
|
153
|
+
return self
|
154
|
+
|
155
|
+
where_query = WhereCondition[T](function=conditions, instances=(self._model,), **kwargs)
|
146
156
|
self._query_list["where"].append(where_query)
|
147
157
|
return self
|
148
158
|
|
@@ -152,6 +162,22 @@ class MySQLStatements[T: Table](AbstractSQLStatements[T, MySQLConnection]):
|
|
152
162
|
self._query_list["order"].append(order)
|
153
163
|
return self
|
154
164
|
|
165
|
+
@override
|
166
|
+
def concat[*Ts](self, selector: Callable[[T], tuple[*Ts]], alias: bool = True, alias_name: str = "CONCAT") -> IAggregate[T]:
|
167
|
+
return func.Concat[T](self._model, selector, alias=alias, alias_name=alias_name)
|
168
|
+
|
169
|
+
@override
|
170
|
+
def max[TProp](self, column: Callable[[T], TProp], alias: bool = True, alias_name: str = "max") -> TProp:
|
171
|
+
return func.Max[T](self._model, column=column, alias=alias, alias_name=alias_name)
|
172
|
+
|
173
|
+
@override
|
174
|
+
def min[TProp](self, column: Callable[[T], TProp], alias: bool = True, alias_name: str = "min") -> TProp:
|
175
|
+
return func.Min[T](self._model, column=column, alias=alias, alias_name=alias_name)
|
176
|
+
|
177
|
+
@override
|
178
|
+
def sum[TProp](self, column: Callable[[T], TProp], alias: bool = True, alias_name: str = "sum") -> TProp:
|
179
|
+
return func.Sum[T](self._model, column=column, alias=alias, alias_name=alias_name)
|
180
|
+
|
155
181
|
@override
|
156
182
|
def select[TValue, TFlavour, *Ts](self, selector: Optional[Callable[[T], tuple[TValue, *Ts]]] = lambda: None, *, flavour: Optional[Type[TFlavour]] = None, by: JoinType = JoinType.INNER_JOIN):
|
157
183
|
if len(inspect.signature(selector).parameters) == 0:
|
@@ -191,31 +217,46 @@ class MySQLStatements[T: Table](AbstractSQLStatements[T, MySQLConnection]):
|
|
191
217
|
return tuple([res[0] for res in response])
|
192
218
|
|
193
219
|
@override
|
194
|
-
def group_by[
|
195
|
-
|
220
|
+
def group_by[*Ts](self, column: str | Callable[[T], Any]) -> IStatements_two_generic[T, MySQLConnection]:
|
221
|
+
if isinstance(column, str):
|
222
|
+
groupby = GroupBy[T, tuple[*Ts]](self._model, lambda x: column)
|
223
|
+
else:
|
224
|
+
groupby = GroupBy[T, tuple[*Ts]](self._model, column)
|
225
|
+
# Only can be one LIMIT SQL parameter. We only use the last LimitQuery
|
226
|
+
self._query_list["group by"].append(groupby)
|
227
|
+
return self
|
196
228
|
|
197
229
|
@override
|
198
230
|
def _build(self) -> str:
|
199
231
|
query: str = ""
|
200
232
|
|
201
|
-
# self.__create_necessary_inner_join()
|
202
233
|
for x in self.__order__:
|
203
234
|
sub_query: Optional[list[IQuery]] = self._query_list.get(x, None)
|
204
|
-
if sub_query is
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
235
|
+
if sub_query is None:
|
236
|
+
continue
|
237
|
+
|
238
|
+
if isinstance(sub_query[0], WhereCondition):
|
239
|
+
query_ = self.__build_where_clause(sub_query)
|
240
|
+
|
241
|
+
# we must check if any join already exists on query string
|
242
|
+
elif isinstance(sub_query[0], JoinSelector):
|
243
|
+
select_query: str = self._query_list["select"][0].query
|
244
|
+
query_ = ""
|
245
|
+
for join in sub_query:
|
246
|
+
if join.query not in select_query:
|
247
|
+
query_ += f"\n{join.query}"
|
248
|
+
|
249
|
+
elif isinstance((select := sub_query[0]), Select):
|
250
|
+
query_: str = ""
|
251
|
+
where_joins = self.__create_necessary_inner_join()
|
252
|
+
if where_joins:
|
253
|
+
select._fk_relationship.update(where_joins)
|
254
|
+
query_ = select.query
|
255
|
+
|
256
|
+
else:
|
257
|
+
query_ = "\n".join([x.query for x in sub_query])
|
258
|
+
|
259
|
+
query += f"\n{query_}" if query != "" else query_
|
219
260
|
self._query_list.clear()
|
220
261
|
return query
|
221
262
|
|
@@ -227,3 +268,19 @@ class MySQLStatements[T: Table](AbstractSQLStatements[T, MySQLConnection]):
|
|
227
268
|
and_, clause = q.split(" ", maxsplit=1)
|
228
269
|
query += f" {and_} ({clause})"
|
229
270
|
return query
|
271
|
+
|
272
|
+
def __create_necessary_inner_join(self) -> Optional[set[tuple[Type[Table], Type[Table]]]]:
|
273
|
+
# When we applied filters in any table that we wont select any column, we need to add manually all neccessary joins to achieve positive result.
|
274
|
+
if "where" not in self._query_list:
|
275
|
+
return None
|
276
|
+
|
277
|
+
res = []
|
278
|
+
for where in self._query_list["where"]:
|
279
|
+
where: AbstractWhere
|
280
|
+
|
281
|
+
tables = where.get_involved_tables()
|
282
|
+
|
283
|
+
if tables:
|
284
|
+
[res.append(x) for x in tables]
|
285
|
+
|
286
|
+
return set(res)
|
@@ -1,19 +1,19 @@
|
|
1
1
|
ormlambda/__init__.py,sha256=L-Enc4FPmW3ldBMnWOU3gLn9i4FEc7sQzLWy2mIEti8,538
|
2
2
|
ormlambda/common/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
3
3
|
ormlambda/common/abstract_classes/__init__.py,sha256=tk2J4Mn_nD-1ZjtMVBE5FH7KR_8ppN_1Kx1s6c38GjM,167
|
4
|
-
ormlambda/common/abstract_classes/abstract_model.py,sha256=
|
5
|
-
ormlambda/common/abstract_classes/decomposition_query.py,sha256=
|
4
|
+
ormlambda/common/abstract_classes/abstract_model.py,sha256=0mGoW-MF0bX1VrAp2AJZ8Nk_BV7N_2NtzZoUFCg5Wm4,4595
|
5
|
+
ormlambda/common/abstract_classes/decomposition_query.py,sha256=c-Vo0f2dnVCv9Qsmqt9AZaZAYvyYhtZFdc3HKyHCMZ0,11396
|
6
6
|
ormlambda/common/abstract_classes/non_query_base.py,sha256=5jhvyT7OZaJxlGp9XMP3vQ4ei5QQZBn-fFtJnD640mE,980
|
7
7
|
ormlambda/common/abstract_classes/query_base.py,sha256=6qUFPwsVx45kUW3b66pHiSyjhcH4mzbdkddlGeUnG7c,266
|
8
8
|
ormlambda/common/enums/__init__.py,sha256=4lVKCHi1JalwgNzjsAXqX-C54NJEH83y2v5baMO8fN4,103
|
9
9
|
ormlambda/common/enums/condition_types.py,sha256=mDPMrtzZu4IYv3-q5Zw4NNgwUoNAx4lih5SIDFRn1Qo,309
|
10
10
|
ormlambda/common/enums/join_type.py,sha256=7LEhE34bzYOwJxe8yxPJo_EjQpGylgClAPX1Wt3z4n4,292
|
11
11
|
ormlambda/common/interfaces/IAggregate.py,sha256=i9zZIYrstP2oolUYqR-udeQQl7M0NwSzrr-VUL0b5HI,271
|
12
|
-
ormlambda/common/interfaces/IDecompositionQuery.py,sha256=
|
12
|
+
ormlambda/common/interfaces/IDecompositionQuery.py,sha256=dHdCxezbWwy-c4U4po2hQB8f_wa0wGFvA2TKaHBx0Do,1363
|
13
13
|
ormlambda/common/interfaces/INonQueryCommand.py,sha256=7CjLW4sKqkR5zUIGvhRXOtzTs6vypJW1a9EJHlgCw2c,260
|
14
14
|
ormlambda/common/interfaces/IQueryCommand.py,sha256=hfzCosK4-n8RJIb2PYs8b0qU3TNmfYluZXBf47KxxKs,331
|
15
|
-
ormlambda/common/interfaces/IRepositoryBase.py,sha256=
|
16
|
-
ormlambda/common/interfaces/IStatements.py,sha256=
|
15
|
+
ormlambda/common/interfaces/IRepositoryBase.py,sha256=zGm7tDrFLKj3FMYN-MWI-em3INws27g2yByNYYMx0qk,1126
|
16
|
+
ormlambda/common/interfaces/IStatements.py,sha256=df3pGRFSwyBcFct0ntMy8E9RNCHreXTO-qirdetS05M,10674
|
17
17
|
ormlambda/common/interfaces/__init__.py,sha256=00ca9a-u_A8DzyEyxPfBMxfqLKFzzUgJaeNmoRitAbA,360
|
18
18
|
ormlambda/components/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
19
19
|
ormlambda/components/delete/IDelete.py,sha256=06ZEdbKBxsHSwsGMBu0E1om4WJjojZAm-L3b95eQrcc,139
|
@@ -32,27 +32,29 @@ ormlambda/components/where/__init__.py,sha256=mI-ylB6cTTVf3rtCX54apgZrMP6y9tTD7-
|
|
32
32
|
ormlambda/components/where/abstract_where.py,sha256=93tIJBC81OUUVV6il7mISibBwqJeodQdFFQ9DShDKOQ,344
|
33
33
|
ormlambda/databases/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
34
34
|
ormlambda/databases/my_sql/__init__.py,sha256=3PbOp4WqxJzFOSRwBozqyNtQi25cLLdiJFPDzEnSI70,115
|
35
|
-
ormlambda/databases/my_sql/clauses/__init__.py,sha256=
|
35
|
+
ormlambda/databases/my_sql/clauses/__init__.py,sha256=F7p---sNQBefi_dgydV6Wp1YuOwDzvSQOdbcjWtBi2k,767
|
36
36
|
ormlambda/databases/my_sql/clauses/count.py,sha256=UFJD-ELp-xvOyPbvYX37GvRZsP8M_axambnI7_h91yA,1177
|
37
37
|
ormlambda/databases/my_sql/clauses/create_database.py,sha256=WnWaAuhxeE71NZKXW37WZ-msRqjum7TFCSRK1IGdSTE,1279
|
38
38
|
ormlambda/databases/my_sql/clauses/delete.py,sha256=nUKNQgwF5YUfzk2icWpecYjrGk5DeXpp7eiwtWCf_3c,1924
|
39
39
|
ormlambda/databases/my_sql/clauses/drop_database.py,sha256=nMM0YUbcH0D9X3bU70Uc6S_dsIrAZy-IrYuIKrQZNrg,505
|
40
40
|
ormlambda/databases/my_sql/clauses/drop_table.py,sha256=meX4e-pVPQ7UwlPSHV5e9HHRblI1BlkLSc7ssl8WUiI,592
|
41
|
+
ormlambda/databases/my_sql/clauses/group_by.py,sha256=xG8YhdaDWBm99EFMkzCsBJNhHOJy5lvXmpaHu3jClro,1042
|
41
42
|
ormlambda/databases/my_sql/clauses/insert.py,sha256=LO9H8VVK3j62dICXqpEUXKxOHPxkD1LGvogmDq2zmho,2805
|
42
43
|
ormlambda/databases/my_sql/clauses/joins.py,sha256=U6JnUvQo7AXyEeK-X1jMvckXefgAB7ugSmJCZhH1XQI,3058
|
43
44
|
ormlambda/databases/my_sql/clauses/limit.py,sha256=a4lI8FVRKpfXwBQTXdkbVtlQkmzcjE20ymiCy1IaSc4,391
|
44
45
|
ormlambda/databases/my_sql/clauses/offset.py,sha256=81170JhsQndjKlDfQj1ll-tiYHQbW8SuU4IE3mhQF7Y,395
|
45
|
-
ormlambda/databases/my_sql/clauses/order.py,sha256=
|
46
|
-
ormlambda/databases/my_sql/clauses/select.py,sha256=
|
46
|
+
ormlambda/databases/my_sql/clauses/order.py,sha256=RVqyEtD0InnOPAmRvjtNJ-vrAy0V9OHMLoFB8TkpX0I,1137
|
47
|
+
ormlambda/databases/my_sql/clauses/select.py,sha256=unJBteFK5D360KnIPyqz8OMaVJqXJlI5Kkp6u0JJ1vU,1574
|
47
48
|
ormlambda/databases/my_sql/clauses/update.py,sha256=3Htw0_PT3EckEiF214-V2r63lcNoRBroKZI9yg48Ddg,1867
|
48
49
|
ormlambda/databases/my_sql/clauses/upsert.py,sha256=eW2pQ4ax-GKuXiaWKoSRSS1GrHuILJBsmj83ADbBQ34,1951
|
49
50
|
ormlambda/databases/my_sql/clauses/where_condition.py,sha256=UgU5vnTqFAx91wKwnECpww5tETDZ9F7IdC_SiZOgZhI,8336
|
50
|
-
ormlambda/databases/my_sql/functions/__init__.py,sha256=
|
51
|
+
ormlambda/databases/my_sql/functions/__init__.py,sha256=hA8t3mUpV2p-pO4TVp5rjC5Yp7aIkWPsS8NpLi3DUh0,171
|
51
52
|
ormlambda/databases/my_sql/functions/concat.py,sha256=cZztl5eSATpYMKVKfyPbul6OocaUkaEGpt3uWmhf-3o,1177
|
52
|
-
ormlambda/databases/my_sql/functions/group_by.py,sha256=ym1L6RBA70hmzrkJ-IA_-6Esq7eoVgNdf1vWpqxRq-8,1080
|
53
53
|
ormlambda/databases/my_sql/functions/max.py,sha256=zrO_RBKsHhyokEmSpPI6Yg5OY6Jf4GGp2RveBJdOuuA,1190
|
54
|
-
ormlambda/databases/my_sql/
|
55
|
-
ormlambda/databases/my_sql/
|
54
|
+
ormlambda/databases/my_sql/functions/min.py,sha256=SEVuUdIJNz9zM5za1kLTWalFkhErjsjyBb8SU8n0F94,1190
|
55
|
+
ormlambda/databases/my_sql/functions/sum.py,sha256=akKYr2dI8TZS5MDvybfHn_idhPOvEH0cj6mDRQIHe-M,1188
|
56
|
+
ormlambda/databases/my_sql/repository.py,sha256=fSAAmO_T5mC1bodOVZn5CY9JSfRq4VhsdlWT1JLl7Zw,6927
|
57
|
+
ormlambda/databases/my_sql/statements.py,sha256=inUEyLUl3Z6TxE7PpJUWw0SZBoO_JbnrS_XL_wCyHn4,11873
|
56
58
|
ormlambda/model_base.py,sha256=RrAATQWX_bHJ0ZQ5sCHyJKA4NiR7ZJY4I6dqhnGWWAc,1216
|
57
59
|
ormlambda/utils/__init__.py,sha256=ywMdWqmA2jHj19-W-S04yfaYF5hv4IZ1lZDq0B8Jnjs,142
|
58
60
|
ormlambda/utils/column.py,sha256=5FAGzCU4yvNS4MhwJJ5i73h7RvHD5UCVox0NdzMsMiE,1945
|
@@ -69,7 +71,7 @@ ormlambda/utils/module_tree/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMp
|
|
69
71
|
ormlambda/utils/module_tree/dfs_traversal.py,sha256=lSF03G63XtJFLp03ueAmsHMBvhUkjptDbK3IugXm8iU,1425
|
70
72
|
ormlambda/utils/module_tree/dynamic_module.py,sha256=zwvjU3U2cz6H2CDp9Gncs5D5bSAyfITNa2SDqFDl8rw,8551
|
71
73
|
ormlambda/utils/table_constructor.py,sha256=8Apm44K6MiYMK3PQyK74MUV18OatbFI9eDLAVklQO0w,11660
|
72
|
-
ormlambda-2.
|
73
|
-
ormlambda-2.
|
74
|
-
ormlambda-2.
|
75
|
-
ormlambda-2.
|
74
|
+
ormlambda-2.8.0.dist-info/LICENSE,sha256=xBprFw8GJLdHMOoUqDk0427EvjIcbEREvXXVFULuuXU,1080
|
75
|
+
ormlambda-2.8.0.dist-info/METADATA,sha256=HV3vUXqD2StgsPEk4VwRtPLp44DRjIUgSoMTRsWAkNw,8428
|
76
|
+
ormlambda-2.8.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
77
|
+
ormlambda-2.8.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|