ormlambda 2.9.4__py3-none-any.whl → 2.11.1__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/decomposition_query.py +97 -55
- ormlambda/common/errors/__init__.py +7 -2
- ormlambda/common/interfaces/ICustomAlias.py +1 -1
- ormlambda/common/interfaces/IDecompositionQuery.py +7 -9
- ormlambda/common/interfaces/IStatements.py +26 -10
- ormlambda/common/interfaces/__init__.py +7 -6
- ormlambda/databases/my_sql/clauses/__init__.py +1 -0
- ormlambda/databases/my_sql/clauses/alias.py +1 -1
- ormlambda/databases/my_sql/clauses/where_condition.py +4 -1
- ormlambda/databases/my_sql/statements.py +23 -7
- {ormlambda-2.9.4.dist-info → ormlambda-2.11.1.dist-info}/METADATA +1 -1
- {ormlambda-2.9.4.dist-info → ormlambda-2.11.1.dist-info}/RECORD +14 -14
- {ormlambda-2.9.4.dist-info → ormlambda-2.11.1.dist-info}/LICENSE +0 -0
- {ormlambda-2.9.4.dist-info → ormlambda-2.11.1.dist-info}/WHEEL +0 -0
@@ -6,17 +6,26 @@ import abc
|
|
6
6
|
from ormlambda import Table
|
7
7
|
|
8
8
|
from ormlambda.utils.lambda_disassembler.tree_instruction import TreeInstruction, TupleInstruction, NestedElement
|
9
|
-
from ormlambda.common.interfaces import IAggregate, IDecompositionQuery
|
9
|
+
from ormlambda.common.interfaces import IAggregate, IDecompositionQuery, ICustomAlias
|
10
|
+
from ormlambda.common.interfaces.IDecompositionQuery import IDecompositionQuery_one_arg
|
10
11
|
from ormlambda import JoinType, ForeignKey
|
11
12
|
from ormlambda.databases.my_sql.clauses.joins import JoinSelector
|
12
13
|
|
13
|
-
from ..errors import
|
14
|
+
from ..errors import UnmatchedLambdaParameterError
|
14
15
|
|
15
|
-
type ClauseDataType = property | str
|
16
|
+
type ClauseDataType = property | str | ICustomAlias
|
16
17
|
type AliasType[T] = tp.Type[Table] | tp.Callable[[tp.Type[Table]], T]
|
17
18
|
|
19
|
+
type ValueType = tp.Union[
|
20
|
+
property,
|
21
|
+
IAggregate,
|
22
|
+
Table,
|
23
|
+
str,
|
24
|
+
ICustomAlias,
|
25
|
+
]
|
18
26
|
|
19
|
-
|
27
|
+
|
28
|
+
class ClauseInfo[T: tp.Type[Table]](IDecompositionQuery_one_arg[T]):
|
20
29
|
@tp.overload
|
21
30
|
def __init__(self, table: T, column: property, alias_children_resolver: tp.Callable[..., str]): ...
|
22
31
|
@tp.overload
|
@@ -34,6 +43,10 @@ class ClauseInfo[T: tp.Type[Table]]:
|
|
34
43
|
def __repr__(self) -> str:
|
35
44
|
return f"{ClauseInfo.__name__}: {self.query}"
|
36
45
|
|
46
|
+
@property
|
47
|
+
def table(self) -> T:
|
48
|
+
return self._table
|
49
|
+
|
37
50
|
@property
|
38
51
|
def column(self) -> ClauseDataType:
|
39
52
|
return self._column
|
@@ -64,6 +77,12 @@ class ClauseInfo[T: tp.Type[Table]]:
|
|
64
77
|
# TODOL: refactor to base the condition in dict with '*' as key. '*' must to work as special character
|
65
78
|
return f"'{data}'" if data != DecompositionQueryBase.CHAR else data
|
66
79
|
|
80
|
+
elif isinstance(data, ICustomAlias):
|
81
|
+
return data.all_clauses[0].column
|
82
|
+
|
83
|
+
else:
|
84
|
+
raise NotImplementedError(f"type of value '{type(data)}' is not implemented.")
|
85
|
+
|
67
86
|
def __create_value_string(self, name: str) -> str:
|
68
87
|
if isinstance(self._row_column, property):
|
69
88
|
return self.concat_with_alias(f"{self._table.__table_name__}.{name}")
|
@@ -74,11 +93,9 @@ class ClauseInfo[T: tp.Type[Table]]:
|
|
74
93
|
return self.concat_with_alias(self.column)
|
75
94
|
|
76
95
|
def concat_with_alias(self, column_name: str) -> str:
|
77
|
-
|
78
|
-
|
79
|
-
if not alias:
|
96
|
+
if not self._alias:
|
80
97
|
return column_name
|
81
|
-
return f"{column_name} as `{
|
98
|
+
return f"{column_name} as `{self._alias}`"
|
82
99
|
|
83
100
|
|
84
101
|
class DecompositionQueryBase[T: tp.Type[Table], *Ts](IDecompositionQuery[T, *Ts]):
|
@@ -154,6 +171,9 @@ class DecompositionQueryBase[T: tp.Type[Table], *Ts](IDecompositionQuery[T, *Ts]
|
|
154
171
|
"""
|
155
172
|
lambda_vars = tuple(inspect.signature(_lambda).parameters)
|
156
173
|
|
174
|
+
if len(lambda_vars) != (expected := len(self._tables)):
|
175
|
+
raise UnmatchedLambdaParameterError(expected, found_param=lambda_vars)
|
176
|
+
|
157
177
|
# COMMENT: We don't pass a lambda method because lambda reads the las value of 'i'
|
158
178
|
for i, param in enumerate(lambda_vars):
|
159
179
|
self.alias_cache[param] = self._tables[i]
|
@@ -162,20 +182,18 @@ class DecompositionQueryBase[T: tp.Type[Table], *Ts](IDecompositionQuery[T, *Ts]
|
|
162
182
|
def __clauses_list_generetor(self, function: tp.Callable[[T], tp.Any]) -> None:
|
163
183
|
if not callable(function):
|
164
184
|
return None
|
165
|
-
|
166
|
-
|
167
|
-
except TypeError:
|
168
|
-
raise DifferentTablesAndVariablesError
|
185
|
+
|
186
|
+
resolved_function = function(*self._tables)
|
169
187
|
|
170
188
|
tree_list = TreeInstruction(function).to_list()
|
171
189
|
# Python treats string objects as iterable, so we need to prevent this behavior
|
172
190
|
if isinstance(resolved_function, str) or not isinstance(resolved_function, tp.Iterable):
|
173
191
|
resolved_function = (resolved_function,)
|
174
192
|
|
175
|
-
for col_index,
|
193
|
+
for col_index, data in enumerate(resolved_function):
|
176
194
|
ti = tree_list[col_index] if tree_list else TupleInstruction(self.CHAR, NestedElement(self.CHAR))
|
177
195
|
|
178
|
-
values: ClauseInfo | list[ClauseInfo] = self.__identify_value_type(
|
196
|
+
values: ClauseInfo | list[ClauseInfo] = self.__identify_value_type(data, ti)
|
179
197
|
|
180
198
|
if isinstance(values, tp.Iterable):
|
181
199
|
[self.__add_clause(x) for x in values]
|
@@ -184,50 +202,74 @@ class DecompositionQueryBase[T: tp.Type[Table], *Ts](IDecompositionQuery[T, *Ts]
|
|
184
202
|
|
185
203
|
return None
|
186
204
|
|
187
|
-
def __identify_value_type[TProp](self,
|
205
|
+
def __identify_value_type[TProp](self, data: TProp, tuple_instruction: TupleInstruction) -> ClauseInfo[T]:
|
188
206
|
"""
|
189
207
|
A method that behaves based on the variable's type
|
190
208
|
"""
|
191
209
|
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
#
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
210
|
+
def validation(data: TProp, type_: ValueType):
|
211
|
+
is_table: bool = isinstance(data, type) and issubclass(data, type_)
|
212
|
+
return any(
|
213
|
+
[
|
214
|
+
isinstance(data, type_),
|
215
|
+
is_table,
|
216
|
+
]
|
217
|
+
)
|
218
|
+
|
219
|
+
value_type_mapped: dict[tp.Type[ValueType], tp.Callable[[TProp, TupleInstruction], ClauseInfo[T]]] = {
|
220
|
+
property: self._property_type,
|
221
|
+
IAggregate: self._IAggregate_type,
|
222
|
+
Table: self._table_type,
|
223
|
+
str: self._str_type,
|
224
|
+
ICustomAlias: self._ICustomAlias_type,
|
225
|
+
}
|
226
|
+
|
227
|
+
function = next((handler for cls, handler in value_type_mapped.items() if validation(data, cls)), None)
|
228
|
+
|
229
|
+
if not function:
|
230
|
+
raise NotImplementedError(f"type of value '{data}' is not implemented.")
|
231
|
+
|
232
|
+
return function(data, tuple_instruction)
|
233
|
+
|
234
|
+
def _property_type(self, data: property, ti: TupleInstruction):
|
235
|
+
if ti.var == self.CHAR:
|
236
|
+
table_left = self.table
|
237
|
+
else:
|
238
|
+
table_left = self.alias_cache[ti.var]
|
239
|
+
|
240
|
+
if data in table_left.__properties_mapped__:
|
241
|
+
# if self.table != table_left:
|
242
|
+
# self._add_fk_relationship(self.table, table_left)
|
243
|
+
return ClauseInfo[T](table_left, data, self.alias_children_resolver)
|
244
|
+
|
245
|
+
for table in self.tables:
|
246
|
+
try:
|
247
|
+
return self._search_correct_table_for_prop(table, ti, data)
|
248
|
+
except ValueError:
|
249
|
+
continue
|
250
|
+
|
251
|
+
def _IAggregate_type(self, data: IAggregate, ti: TupleInstruction):
|
252
|
+
return ClauseInfo[T](self.table, data, self.alias_children_resolver)
|
253
|
+
|
254
|
+
def _table_type(self, data: tp.Type[Table], ti: TupleInstruction):
|
255
|
+
if data not in self._tables:
|
256
|
+
self.__add_necessary_fk(ti, data)
|
257
|
+
# all columns
|
258
|
+
clauses: list[ClauseInfo] = []
|
259
|
+
for prop in data.__properties_mapped__:
|
260
|
+
if isinstance(prop, property):
|
261
|
+
clauses.append(self.__identify_value_type(prop, ti))
|
262
|
+
return clauses
|
263
|
+
|
264
|
+
def _str_type(self, data: str, ti: TupleInstruction):
|
265
|
+
# COMMENT: use self.table instead self._tables because if we hit this conditional, means that
|
266
|
+
# COMMENT: alias_cache to replace '*' by all columns
|
267
|
+
if self._replace_asterisk_char and (replace_value := self.alias_cache.get(data, None)) is not None:
|
268
|
+
return self.__identify_value_type(replace_value(self.table), ti)
|
269
|
+
return ClauseInfo[T](self.table, data, alias_children_resolver=self.alias_children_resolver)
|
270
|
+
|
271
|
+
def _ICustomAlias_type(self, data: ICustomAlias, ti: TupleInstruction):
|
272
|
+
return ClauseInfo(data.table, data, data.alias_children_resolver)
|
231
273
|
|
232
274
|
def _search_correct_table_for_prop[TTable](self, table: tp.Type[Table], tuple_instruction: TupleInstruction, prop: property) -> ClauseInfo[TTable]:
|
233
275
|
temp_table: tp.Type[Table] = table
|
@@ -251,7 +293,7 @@ class DecompositionQueryBase[T: tp.Type[Table], *Ts](IDecompositionQuery[T, *Ts]
|
|
251
293
|
|
252
294
|
def __add_clause[Tc: tp.Type[Table]](self, clause: ClauseInfo[Tc]) -> None:
|
253
295
|
self._all_clauses.append(clause)
|
254
|
-
self._clauses_group_by_tables[clause.
|
296
|
+
self._clauses_group_by_tables[clause.table].append(clause)
|
255
297
|
return None
|
256
298
|
|
257
299
|
def __add_necessary_fk(self, tuple_instruction: TupleInstruction, tables: tp.Type[Table]) -> None:
|
@@ -1,3 +1,8 @@
|
|
1
|
-
class
|
1
|
+
class UnmatchedLambdaParameterError(Exception):
|
2
|
+
def __init__(self, expected_params: int, found_param: tuple[str, ...], *args: object) -> None:
|
3
|
+
super().__init__(*args)
|
4
|
+
self.expected_params = expected_params
|
5
|
+
self.found_param: tuple[str, ...] = found_param
|
6
|
+
|
2
7
|
def __str__(self) -> str:
|
3
|
-
return "
|
8
|
+
return f"Unmatched number of parameters in lambda function with the number of tables: Expected {self.expected_params} parameters but found {str(self.found_param)}."
|
@@ -12,11 +12,17 @@ if tp.TYPE_CHECKING:
|
|
12
12
|
from .IQueryCommand import IQuery
|
13
13
|
|
14
14
|
|
15
|
-
class
|
15
|
+
class IDecompositionQuery_one_arg[T: tp.Type[Table]](IQuery):
|
16
16
|
@property
|
17
17
|
@abc.abstractmethod
|
18
18
|
def table(self) -> T: ...
|
19
19
|
|
20
|
+
@property
|
21
|
+
@abc.abstractmethod
|
22
|
+
def alias(self) -> bool: ...
|
23
|
+
|
24
|
+
|
25
|
+
class IDecompositionQuery[T: tp.Type[Table], *Ts](IDecompositionQuery_one_arg[T], IQuery):
|
20
26
|
@property
|
21
27
|
@abc.abstractmethod
|
22
28
|
def tables(self) -> tuple[*Ts]: ...
|
@@ -37,14 +43,6 @@ class IDecompositionQuery[T: tp.Type[Table], *Ts](IQuery):
|
|
37
43
|
@abc.abstractmethod
|
38
44
|
def fk_relationship(self) -> set[tuple[tp.Type[Table], tp.Type[Table]]]: ...
|
39
45
|
|
40
|
-
@property
|
41
|
-
@abc.abstractmethod
|
42
|
-
def query(self) -> str: ...
|
43
|
-
|
44
|
-
@property
|
45
|
-
@abc.abstractmethod
|
46
|
-
def alias(self) -> bool: ...
|
47
|
-
|
48
46
|
@property
|
49
47
|
@abc.abstractmethod
|
50
48
|
def alias_name(self) -> tp.Optional[str]: ...
|
@@ -35,7 +35,7 @@ type SelectRes10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10] = tuple[*SelectRes9[T1
|
|
35
35
|
|
36
36
|
|
37
37
|
type WhereCondition[T, T1] = Callable[[T, T1], bool]
|
38
|
-
type JoinCondition[T, T1] = tuple[T1, WhereCondition[T, T1]]
|
38
|
+
type JoinCondition[T, T1] = tuple[T1, WhereCondition[T, T1], Optional[JoinType]]
|
39
39
|
|
40
40
|
type TupleJoins1[T, T1] = tuple[JoinCondition[T, T1]]
|
41
41
|
type TupleJoins2[T, T1, T2] = tuple[*TupleJoins1[T, T1], JoinCondition[T, T2]]
|
@@ -227,22 +227,29 @@ class IStatements[T, *Ts](ABC):
|
|
227
227
|
# region join
|
228
228
|
|
229
229
|
@overload
|
230
|
-
def join[T1](self,
|
230
|
+
def join[T1](self, table: T1, relation: WhereCondition[T, T1], join_type: Optional[JoinType]) -> IStatements[T, T1]: ...
|
231
231
|
@overload
|
232
|
-
def join[T1](self,
|
232
|
+
def join[T1](self, table: JoinCondition[T, T1]) -> IStatements[T, T1]: ...
|
233
233
|
@overload
|
234
|
-
def join[T1
|
234
|
+
def join[T1](self, table: TupleJoins1[T, T1]) -> IStatements[T, T1]: ...
|
235
235
|
@overload
|
236
|
-
def join[T1, T2
|
236
|
+
def join[T1, T2](self, table: TupleJoins2[T, T1, T2]) -> IStatements[T, T1, T2]: ...
|
237
237
|
@overload
|
238
|
-
def join[T1, T2, T3
|
238
|
+
def join[T1, T2, T3](self, table: TupleJoins3[T, T1, T2, T3]) -> IStatements[T, T1, T2, T3]: ...
|
239
239
|
@overload
|
240
|
-
def join[T1, T2, T3, T4
|
240
|
+
def join[T1, T2, T3, T4](self, table: TupleJoins4[T, T1, T2, T3, T4]) -> IStatements[T, T1, T2, T3, T4]: ...
|
241
241
|
@overload
|
242
|
-
def join[T1, T2, T3, T4, T5
|
242
|
+
def join[T1, T2, T3, T4, T5](self, table: TupleJoins5[T, T1, T2, T3, T4, T5]) -> IStatements[T, T1, T2, T3, T4, T5]: ...
|
243
|
+
@overload
|
244
|
+
def join[T1, T2, T3, T4, T5, T6](self, table: TupleJoins6[T, T1, T2, T3, T4, T5, T6]) -> IStatements[T, T1, T2, T3, T4, T5, T6]: ...
|
243
245
|
|
244
246
|
@abstractmethod
|
245
|
-
def join[*FKTables](
|
247
|
+
def join[*FKTables](
|
248
|
+
self,
|
249
|
+
table: Optional[T] = ...,
|
250
|
+
relation: Optional[WhereCondition[T, FKTables]] = ...,
|
251
|
+
join_type: Optional[JoinType] = ...,
|
252
|
+
) -> IStatements[T, *FKTables]: ...
|
246
253
|
|
247
254
|
# endregion
|
248
255
|
# region select
|
@@ -304,7 +311,13 @@ class IStatements[T, *Ts](ABC):
|
|
304
311
|
@overload
|
305
312
|
def select_one[TFlavour](self, selector: Callable[[T, *Ts], tuple], *, by: Optional[Enum] = ..., flavour: Type[TFlavour]) -> TFlavour: ...
|
306
313
|
@abstractmethod
|
307
|
-
def select_one[TValue, TFlavour, *Ts](
|
314
|
+
def select_one[TValue, TFlavour, *Ts](
|
315
|
+
self,
|
316
|
+
selector: Optional[Callable[[T, *Ts], tuple[TValue, *Ts]]] = lambda: None,
|
317
|
+
*,
|
318
|
+
flavour: Type[TFlavour] = ...,
|
319
|
+
by: Optional[Enum] = ...,
|
320
|
+
): ...
|
308
321
|
|
309
322
|
# endregion
|
310
323
|
# region group_by
|
@@ -316,6 +329,9 @@ class IStatements[T, *Ts](ABC):
|
|
316
329
|
@abstractmethod
|
317
330
|
def _build(self) -> str: ...
|
318
331
|
|
332
|
+
@abstractmethod
|
333
|
+
def alias(self, column: Callable[[T, *Ts], Any], alias: str) -> IStatements[T, *Ts]: ...
|
334
|
+
|
319
335
|
|
320
336
|
class IStatements_two_generic[T: Table, *Ts, TRepo](IStatements[T, *Ts]):
|
321
337
|
@property
|
@@ -1,6 +1,7 @@
|
|
1
|
-
from .IQueryCommand import IQuery
|
2
|
-
from .INonQueryCommand import INonQueryCommand
|
3
|
-
from .IRepositoryBase import IRepositoryBase
|
4
|
-
from .IStatements import IStatements, IStatements_two_generic
|
5
|
-
from .IDecompositionQuery import IDecompositionQuery
|
6
|
-
from .IAggregate import IAggregate
|
1
|
+
from .IQueryCommand import IQuery as IQuery
|
2
|
+
from .INonQueryCommand import INonQueryCommand as INonQueryCommand
|
3
|
+
from .IRepositoryBase import IRepositoryBase as IRepositoryBase
|
4
|
+
from .IStatements import IStatements as IStatements, IStatements_two_generic as IStatements_two_generic
|
5
|
+
from .IDecompositionQuery import IDecompositionQuery as IDecompositionQuery
|
6
|
+
from .IAggregate import IAggregate as IAggregate
|
7
|
+
from .ICustomAlias import ICustomAlias as ICustomAlias
|
@@ -5,7 +5,7 @@ from ormlambda import Table
|
|
5
5
|
from ormlambda.common.interfaces import ICustomAlias
|
6
6
|
|
7
7
|
|
8
|
-
class Alias[T: tp.Type[Table], *Ts](DecompositionQueryBase[T
|
8
|
+
class Alias[T: tp.Type[Table], *Ts](DecompositionQueryBase[T, *Ts], ICustomAlias[T, *Ts]):
|
9
9
|
def __init__(
|
10
10
|
self,
|
11
11
|
table: T,
|
@@ -5,6 +5,7 @@ from ormlambda.common.enums import ConditionType
|
|
5
5
|
from ormlambda.utils.lambda_disassembler.tree_instruction import TreeInstruction, TupleInstruction
|
6
6
|
from ormlambda.common.interfaces.IQueryCommand import IQuery
|
7
7
|
from ormlambda.components.where.abstract_where import AbstractWhere
|
8
|
+
from ormlambda.common.errors import UnmatchedLambdaParameterError
|
8
9
|
from ormlambda import Table
|
9
10
|
|
10
11
|
|
@@ -69,7 +70,9 @@ class WhereCondition[T: Type[Table], *Inst](AbstractWhere):
|
|
69
70
|
"""
|
70
71
|
The method is responsible for mapping the variables present in the lambda function so that they are replaced with the instance of the model Table.
|
71
72
|
"""
|
72
|
-
|
73
|
+
lamda_param = inspect.signature(self._function).parameters
|
74
|
+
if len(lamda_param) != (expected := len(self._instances)):
|
75
|
+
raise UnmatchedLambdaParameterError(expected, found_param=tuple(lamda_param))
|
73
76
|
|
74
77
|
_temp_instances = list(self._instances)[::-1] # we copied and translated tuple instance due to pop each value in order to param
|
75
78
|
new_dicc: dict[str, Table] = {}
|
@@ -30,6 +30,7 @@ from .clauses import UpdateQuery
|
|
30
30
|
from .clauses import WhereCondition
|
31
31
|
from .clauses import Count
|
32
32
|
from .clauses import GroupBy
|
33
|
+
from .clauses import Alias
|
33
34
|
|
34
35
|
|
35
36
|
from ormlambda.utils import Table
|
@@ -157,7 +158,7 @@ class MySQLStatements[T: Table, *Ts](AbstractSQLStatements[T, *Ts, MySQLConnecti
|
|
157
158
|
self._query_list["where"].append(WhereCondition[T](function=x, instances=self._models, **kwargs))
|
158
159
|
return self
|
159
160
|
|
160
|
-
where_query = WhereCondition[T](function=conditions, instances=
|
161
|
+
where_query = WhereCondition[T](function=conditions, instances=self._models, **kwargs)
|
161
162
|
self._query_list["where"].append(where_query)
|
162
163
|
return self
|
163
164
|
|
@@ -184,13 +185,24 @@ class MySQLStatements[T: Table, *Ts](AbstractSQLStatements[T, *Ts, MySQLConnecti
|
|
184
185
|
return func.Sum[T](self._model, column=column, alias=alias, alias_name=alias_name)
|
185
186
|
|
186
187
|
@override
|
187
|
-
def join[*FKTables](
|
188
|
-
|
189
|
-
|
188
|
+
def join[*FKTables](
|
189
|
+
self,
|
190
|
+
table: Optional[T] = None,
|
191
|
+
relation: Optional[WhereCondition[T, *FKTables]] = None,
|
192
|
+
join_type: Optional[JoinType] = None,
|
193
|
+
) -> IStatements_two_generic[T, *FKTables, MySQLConnection]:
|
194
|
+
if isinstance(table, type) and issubclass(table, Table):
|
195
|
+
joins = ((table, relation, join_type),)
|
196
|
+
else:
|
197
|
+
if any(len(x) != 3 for x in table):
|
198
|
+
raise ValueError("Each tuple inside of 'join' method must contain the referenced table, relation between columns and join type")
|
199
|
+
joins = table
|
200
|
+
|
190
201
|
new_tables: list[Type[Table]] = [self._model]
|
191
|
-
|
202
|
+
|
203
|
+
for table, where, by in joins:
|
192
204
|
new_tables.append(table)
|
193
|
-
join_query = JoinSelector[T, type(table)](self._model, table, by=
|
205
|
+
join_query = JoinSelector[T, type(table)](self._model, table, by=by, where=where)
|
194
206
|
self._query_list["join"].append(join_query)
|
195
207
|
self._models = new_tables
|
196
208
|
return self
|
@@ -217,7 +229,7 @@ class MySQLStatements[T: Table, *Ts](AbstractSQLStatements[T, *Ts, MySQLConnecti
|
|
217
229
|
self._query_list["select"].append(select)
|
218
230
|
|
219
231
|
self._query: str = self._build()
|
220
|
-
|
232
|
+
|
221
233
|
if flavour:
|
222
234
|
result = self._return_flavour(self.query, flavour, select, **kwargs)
|
223
235
|
if issubclass(flavour, tuple) and isinstance(selector(*self._models), property):
|
@@ -252,6 +264,10 @@ class MySQLStatements[T: Table, *Ts](AbstractSQLStatements[T, *Ts, MySQLConnecti
|
|
252
264
|
self._query_list["group by"].append(groupby)
|
253
265
|
return self
|
254
266
|
|
267
|
+
@override
|
268
|
+
def alias(self, column: Callable[[T, *Ts], Any], alias: str) -> IStatements_two_generic[T, *Ts, MySQLConnection]:
|
269
|
+
return Alias[T, *Ts](self.models, column, alias_name=alias)
|
270
|
+
|
255
271
|
@override
|
256
272
|
@clear_list
|
257
273
|
def _build(self) -> str:
|
@@ -2,21 +2,21 @@ ormlambda/__init__.py,sha256=lWQxjf2cQ2bXenNaDpoy2Bar6imiPlzc4nK0hkIYhC0,723
|
|
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
4
|
ormlambda/common/abstract_classes/abstract_model.py,sha256=xmpr7_Hn5r1bRG2UtOKdhlZgXUqgFGuTTXsmm4LqmEI,5100
|
5
|
-
ormlambda/common/abstract_classes/decomposition_query.py,sha256=
|
5
|
+
ormlambda/common/abstract_classes/decomposition_query.py,sha256=rXy4dNU51_JDAtZRl0X6LYlfRHG0TtFnUJ_mEgvb2cU,14944
|
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
|
-
ormlambda/common/errors/__init__.py,sha256=
|
11
|
+
ormlambda/common/errors/__init__.py,sha256=lUwrezLE5xhs2TuGYghtLTKd_YTyo7aOZQCtccuhcYs,486
|
12
12
|
ormlambda/common/interfaces/IAggregate.py,sha256=i9zZIYrstP2oolUYqR-udeQQl7M0NwSzrr-VUL0b5HI,271
|
13
|
-
ormlambda/common/interfaces/ICustomAlias.py,sha256=
|
14
|
-
ormlambda/common/interfaces/IDecompositionQuery.py,sha256=
|
13
|
+
ormlambda/common/interfaces/ICustomAlias.py,sha256=OuNMScDBrYNriRxViPHdyCk1ZTUpFyMKQEm8AWNDqmA,123
|
14
|
+
ormlambda/common/interfaces/IDecompositionQuery.py,sha256=XE7xqWaZSuopYQXMw_3pOmsbLnUiEbZ_DQ0ykVx823M,1471
|
15
15
|
ormlambda/common/interfaces/INonQueryCommand.py,sha256=7CjLW4sKqkR5zUIGvhRXOtzTs6vypJW1a9EJHlgCw2c,260
|
16
16
|
ormlambda/common/interfaces/IQueryCommand.py,sha256=hfzCosK4-n8RJIb2PYs8b0qU3TNmfYluZXBf47KxxKs,331
|
17
17
|
ormlambda/common/interfaces/IRepositoryBase.py,sha256=M4pD4t6tXo5WaRhwu2vsza1FoAj2S-rEJKjPfKeSRn0,1134
|
18
|
-
ormlambda/common/interfaces/IStatements.py,sha256=
|
19
|
-
ormlambda/common/interfaces/__init__.py,sha256=
|
18
|
+
ormlambda/common/interfaces/IStatements.py,sha256=Y8EvTDGSKYgingWbufonwW4F0IEjXGM7HKCFdszmdC8,13291
|
19
|
+
ormlambda/common/interfaces/__init__.py,sha256=miEhv242PB6b-XoB_RCavv8ADdrR-3WYHmDQVubcQzk,459
|
20
20
|
ormlambda/components/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
21
21
|
ormlambda/components/delete/IDelete.py,sha256=06ZEdbKBxsHSwsGMBu0E1om4WJjojZAm-L3b95eQrcc,139
|
22
22
|
ormlambda/components/delete/__init__.py,sha256=X_at2L4QkxDVK1olXhFHqNemkB8Dxbb7BYqv0EJyu7M,102
|
@@ -34,8 +34,8 @@ ormlambda/components/where/__init__.py,sha256=mI-ylB6cTTVf3rtCX54apgZrMP6y9tTD7-
|
|
34
34
|
ormlambda/components/where/abstract_where.py,sha256=93tIJBC81OUUVV6il7mISibBwqJeodQdFFQ9DShDKOQ,344
|
35
35
|
ormlambda/databases/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
36
36
|
ormlambda/databases/my_sql/__init__.py,sha256=3PbOp4WqxJzFOSRwBozqyNtQi25cLLdiJFPDzEnSI70,115
|
37
|
-
ormlambda/databases/my_sql/clauses/__init__.py,sha256=
|
38
|
-
ormlambda/databases/my_sql/clauses/alias.py,sha256=
|
37
|
+
ormlambda/databases/my_sql/clauses/__init__.py,sha256=nBK8DtmuDUJax1kE-QfMiHlm9m6bueyYMjH5YMmpdk4,801
|
38
|
+
ormlambda/databases/my_sql/clauses/alias.py,sha256=nCOCQtqYfs3KVjeX6rIOOqMa7dVeVjfxUxVhAghc6g4,889
|
39
39
|
ormlambda/databases/my_sql/clauses/count.py,sha256=UFJD-ELp-xvOyPbvYX37GvRZsP8M_axambnI7_h91yA,1177
|
40
40
|
ormlambda/databases/my_sql/clauses/create_database.py,sha256=WnWaAuhxeE71NZKXW37WZ-msRqjum7TFCSRK1IGdSTE,1279
|
41
41
|
ormlambda/databases/my_sql/clauses/delete.py,sha256=nUKNQgwF5YUfzk2icWpecYjrGk5DeXpp7eiwtWCf_3c,1924
|
@@ -50,14 +50,14 @@ ormlambda/databases/my_sql/clauses/order.py,sha256=XTMtR5ObAJxq8eTHp392rykQD991e
|
|
50
50
|
ormlambda/databases/my_sql/clauses/select.py,sha256=q-rJWbYtfgKEGf-OOH3ToGY90KXGzH3FnKHTc0xsAbM,1962
|
51
51
|
ormlambda/databases/my_sql/clauses/update.py,sha256=d2nSLiGe8OUk0ASgGxchit_1DL-Yg8U-DUtBbgpfkto,1571
|
52
52
|
ormlambda/databases/my_sql/clauses/upsert.py,sha256=eW2pQ4ax-GKuXiaWKoSRSS1GrHuILJBsmj83ADbBQ34,1951
|
53
|
-
ormlambda/databases/my_sql/clauses/where_condition.py,sha256
|
53
|
+
ormlambda/databases/my_sql/clauses/where_condition.py,sha256=-yVdQEN-q21Fev3_Gc08m00TCHehUYuqD6v4U2AGU7M,8522
|
54
54
|
ormlambda/databases/my_sql/functions/__init__.py,sha256=hA8t3mUpV2p-pO4TVp5rjC5Yp7aIkWPsS8NpLi3DUh0,171
|
55
55
|
ormlambda/databases/my_sql/functions/concat.py,sha256=cZztl5eSATpYMKVKfyPbul6OocaUkaEGpt3uWmhf-3o,1177
|
56
56
|
ormlambda/databases/my_sql/functions/max.py,sha256=zrO_RBKsHhyokEmSpPI6Yg5OY6Jf4GGp2RveBJdOuuA,1190
|
57
57
|
ormlambda/databases/my_sql/functions/min.py,sha256=SEVuUdIJNz9zM5za1kLTWalFkhErjsjyBb8SU8n0F94,1190
|
58
58
|
ormlambda/databases/my_sql/functions/sum.py,sha256=akKYr2dI8TZS5MDvybfHn_idhPOvEH0cj6mDRQIHe-M,1188
|
59
59
|
ormlambda/databases/my_sql/repository.py,sha256=6qrP-JC4tvUxin3ixGKBeuqvU9cl9mkjNCdwjWZQA9Y,9059
|
60
|
-
ormlambda/databases/my_sql/statements.py,sha256=
|
60
|
+
ormlambda/databases/my_sql/statements.py,sha256=7NZM8G60RqB2kd5r1nz8yZmYSz-HWZx-LypaS6rjg8w,13093
|
61
61
|
ormlambda/model_base.py,sha256=_UGTnin-yUi9ecT-28YY6TniIPdrje-jMFD3QXyZD6c,1243
|
62
62
|
ormlambda/utils/__init__.py,sha256=ywMdWqmA2jHj19-W-S04yfaYF5hv4IZ1lZDq0B8Jnjs,142
|
63
63
|
ormlambda/utils/column.py,sha256=SqbX8N63_RwXNrMXuVMOpatDw--aLc47o3kG1sEXhNs,3413
|
@@ -75,7 +75,7 @@ ormlambda/utils/module_tree/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMp
|
|
75
75
|
ormlambda/utils/module_tree/dfs_traversal.py,sha256=lSF03G63XtJFLp03ueAmsHMBvhUkjptDbK3IugXm8iU,1425
|
76
76
|
ormlambda/utils/module_tree/dynamic_module.py,sha256=zwvjU3U2cz6H2CDp9Gncs5D5bSAyfITNa2SDqFDl8rw,8551
|
77
77
|
ormlambda/utils/table_constructor.py,sha256=ch1geCSJIQnnv_D_uzfYk6do533kjtZyeCIh2t0_dkU,10863
|
78
|
-
ormlambda-2.
|
79
|
-
ormlambda-2.
|
80
|
-
ormlambda-2.
|
81
|
-
ormlambda-2.
|
78
|
+
ormlambda-2.11.1.dist-info/LICENSE,sha256=xBprFw8GJLdHMOoUqDk0427EvjIcbEREvXXVFULuuXU,1080
|
79
|
+
ormlambda-2.11.1.dist-info/METADATA,sha256=f_U8kqhXJw36LHdcidqWfxxeUGaudtV9O9tJ8jmJaXE,8462
|
80
|
+
ormlambda-2.11.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
81
|
+
ormlambda-2.11.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|