clear-skies 1.21.0__py3-none-any.whl → 1.21.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.
Potentially problematic release.
This version of clear-skies might be problematic. Click here for more details.
- {clear_skies-1.21.0.dist-info → clear_skies-1.21.1.dist-info}/METADATA +2 -1
- {clear_skies-1.21.0.dist-info → clear_skies-1.21.1.dist-info}/RECORD +6 -6
- clearskies/model.py +37 -33
- clearskies/models.py +43 -43
- {clear_skies-1.21.0.dist-info → clear_skies-1.21.1.dist-info}/LICENSE +0 -0
- {clear_skies-1.21.0.dist-info → clear_skies-1.21.1.dist-info}/WHEEL +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: clear-skies
|
|
3
|
-
Version: 1.21.
|
|
3
|
+
Version: 1.21.1
|
|
4
4
|
Summary: A framework for building backends in the cloud
|
|
5
5
|
Home-page: https://github.com/cmancone/clearskies
|
|
6
6
|
License: MIT
|
|
@@ -25,6 +25,7 @@ Requires-Dist: jose (>=1.0.0,<2.0.0) ; extra == "jose"
|
|
|
25
25
|
Requires-Dist: jwcrypto (>=1.5.6,<2.0.0) ; extra == "jwcrypto"
|
|
26
26
|
Requires-Dist: pymysql (>=1.1.0,<2.0.0) ; extra == "mysql"
|
|
27
27
|
Requires-Dist: requests (>=2.31.0,<3.0.0)
|
|
28
|
+
Requires-Dist: typing-extensions (>=4.12.0,<5.0.0) ; python_version >= "3.10" and python_version < "3.11"
|
|
28
29
|
Project-URL: Repository, https://github.com/cmancone/clearskies
|
|
29
30
|
Description-Content-Type: text/markdown
|
|
30
31
|
|
|
@@ -181,8 +181,8 @@ clearskies/input_requirements/unique.py,sha256=gpbm9uoXcy8WCHsuWqAotwockbjDfJOWi
|
|
|
181
181
|
clearskies/mocks/__init__.py,sha256=T68OUB9gGCX0WoisGzsY3Bt2cCFX7ILHKPqi6XKTJM0,113
|
|
182
182
|
clearskies/mocks/input_output.py,sha256=2wD5GbUyVSkXcBg1GTZ-Oz9VzcYxNHfTlmZAODW-7CI,3898
|
|
183
183
|
clearskies/mocks/models.py,sha256=DCzsnMddBvPoBA8JwwbSOhzY7enQWrosgeYD4gx2deI,5124
|
|
184
|
-
clearskies/model.py,sha256=
|
|
185
|
-
clearskies/models.py,sha256=
|
|
184
|
+
clearskies/model.py,sha256=ZI75_1KP4J-PID2Aw9l_mNHCeY-HOZH887QKdxRoTdg,13511
|
|
185
|
+
clearskies/models.py,sha256=1H5Vohv1U4avN5_YHqULzc7ynZDRytmZ56x775xWTIo,13038
|
|
186
186
|
clearskies/secrets/__init__.py,sha256=ctTmA_etV9G_5U21APWENI1HvThrBS4DidGWRtEDHQs,1053
|
|
187
187
|
clearskies/secrets/additional_configs/__init__.py,sha256=cFCrbtKF5nuR061S2y1iKZp349x-y8Srdwe3VZbfSFU,1119
|
|
188
188
|
clearskies/secrets/additional_configs/mysql_connection_dynamic_producer.py,sha256=fOt2eOrVtQXhnK05XuSfWw9GoX6klxXLisJcFT0ycAE,2562
|
|
@@ -205,7 +205,7 @@ clearskies/tests/simple_api/models/__init__.py,sha256=nUA0W6fgXw_Bxa9CudkaDkC80t
|
|
|
205
205
|
clearskies/tests/simple_api/models/status.py,sha256=PEhPbaQh5qdUNHp8O0gz91LOLENAEBtqSaHxUPXchaM,699
|
|
206
206
|
clearskies/tests/simple_api/models/user.py,sha256=5_P4Tp1tTdX7PkMJ__epPM5MA7JAeVYGas69vcWloLc,819
|
|
207
207
|
clearskies/tests/simple_api/users_api.py,sha256=KYXCgEofDxHeRdQK67txN5oYUPvxxmB8JTku7L-apk4,2344
|
|
208
|
-
clear_skies-1.21.
|
|
209
|
-
clear_skies-1.21.
|
|
210
|
-
clear_skies-1.21.
|
|
211
|
-
clear_skies-1.21.
|
|
208
|
+
clear_skies-1.21.1.dist-info/LICENSE,sha256=3Ehd0g3YOpCj8sqj0Xjq5qbOtjjgk9qzhhD9YjRQgOA,1053
|
|
209
|
+
clear_skies-1.21.1.dist-info/METADATA,sha256=gUmBHTE31EscgWpY1XRDst7EdoQlbySciQkEvh_fdoA,1817
|
|
210
|
+
clear_skies-1.21.1.dist-info/WHEEL,sha256=d2fvjOD7sXsVzChCqf0Ty0JbHKBaLYwDbGQDwQTnJ50,88
|
|
211
|
+
clear_skies-1.21.1.dist-info/RECORD,,
|
clearskies/model.py
CHANGED
|
@@ -5,6 +5,10 @@ from .functional import string
|
|
|
5
5
|
import re
|
|
6
6
|
from .models import Models
|
|
7
7
|
|
|
8
|
+
try:
|
|
9
|
+
from typing_extensions import Self
|
|
10
|
+
except ModuleNotFoundError:
|
|
11
|
+
from typing import Self
|
|
8
12
|
|
|
9
13
|
class Model(Models):
|
|
10
14
|
_configured_columns = None
|
|
@@ -14,14 +18,14 @@ class Model(Models):
|
|
|
14
18
|
_transformed = None
|
|
15
19
|
id_column_name = "id"
|
|
16
20
|
|
|
17
|
-
def __init__(self, backend, columns):
|
|
21
|
+
def __init__(self: Self, backend, columns):
|
|
18
22
|
super().__init__(backend, columns)
|
|
19
23
|
self._transformed = {}
|
|
20
24
|
self._data = {}
|
|
21
25
|
self._previous_data = None
|
|
22
26
|
self._touched_columns = None
|
|
23
27
|
|
|
24
|
-
def model_class(self):
|
|
28
|
+
def model_class(self: Self) -> type[Self]:
|
|
25
29
|
"""
|
|
26
30
|
Return the model class that this models object will find/return instances of
|
|
27
31
|
|
|
@@ -30,7 +34,7 @@ class Model(Models):
|
|
|
30
34
|
return self.__class__
|
|
31
35
|
|
|
32
36
|
@classmethod
|
|
33
|
-
def table_name(cls):
|
|
37
|
+
def table_name(cls: type[Self]) -> str:
|
|
34
38
|
"""Return the name of the table that the model uses for data storage"""
|
|
35
39
|
singular = string.camel_case_to_snake_case(cls.__name__)
|
|
36
40
|
if singular[-1] == "y":
|
|
@@ -40,16 +44,16 @@ class Model(Models):
|
|
|
40
44
|
return f"{singular}s"
|
|
41
45
|
|
|
42
46
|
@abstractmethod
|
|
43
|
-
def columns_configuration(self):
|
|
47
|
+
def columns_configuration(self: Self):
|
|
44
48
|
"""Returns an ordered dictionary with the configuration for the columns"""
|
|
45
49
|
pass
|
|
46
50
|
|
|
47
|
-
def all_columns(self):
|
|
51
|
+
def all_columns(self: Self):
|
|
48
52
|
default = OrderedDict([(self.id_column_name, {"class": UUID})])
|
|
49
53
|
default.update(self.columns_configuration())
|
|
50
54
|
return default
|
|
51
55
|
|
|
52
|
-
def columns(self, overrides=None):
|
|
56
|
+
def columns(self: Self, overrides=None):
|
|
53
57
|
# no caching if we have overrides
|
|
54
58
|
if overrides is not None:
|
|
55
59
|
return self._columns.configure(self.all_columns(), self.__class__, overrides=overrides)
|
|
@@ -58,13 +62,13 @@ class Model(Models):
|
|
|
58
62
|
self._configured_columns = self._columns.configure(self.all_columns(), self.__class__)
|
|
59
63
|
return self._configured_columns
|
|
60
64
|
|
|
61
|
-
def supports_n_plus_one(self):
|
|
65
|
+
def supports_n_plus_one(self: Self):
|
|
62
66
|
return self._backend.supports_n_plus_one
|
|
63
67
|
|
|
64
|
-
def __getitem__(self, column_name):
|
|
68
|
+
def __getitem__(self: Self, column_name):
|
|
65
69
|
return self.__getattr__(column_name)
|
|
66
70
|
|
|
67
|
-
def __getattr__(self, column_name):
|
|
71
|
+
def __getattr__(self: Self, column_name):
|
|
68
72
|
# this should be adjusted to only return None for empty records if the column name corresponds
|
|
69
73
|
# to an actual column in the table.
|
|
70
74
|
if not self.exists:
|
|
@@ -72,13 +76,13 @@ class Model(Models):
|
|
|
72
76
|
|
|
73
77
|
return self.get_transformed_from_data(column_name, self._data)
|
|
74
78
|
|
|
75
|
-
def get(self, column_name, silent=False):
|
|
79
|
+
def get(self: Self, column_name, silent=False):
|
|
76
80
|
if not self.exists:
|
|
77
81
|
return None
|
|
78
82
|
|
|
79
83
|
return self.get_transformed_from_data(column_name, self._data, silent=silent)
|
|
80
84
|
|
|
81
|
-
def get_transformed_from_data(self, column_name, data, cache=True, check_providers=True, silent=False):
|
|
85
|
+
def get_transformed_from_data(self: Self, column_name, data, cache=True, check_providers=True, silent=False):
|
|
82
86
|
if cache and column_name in self._transformed:
|
|
83
87
|
return self._transformed[column_name]
|
|
84
88
|
|
|
@@ -111,18 +115,18 @@ class Model(Models):
|
|
|
111
115
|
return value
|
|
112
116
|
|
|
113
117
|
@property
|
|
114
|
-
def exists(self):
|
|
118
|
+
def exists(self: Self) -> bool:
|
|
115
119
|
return True if (self.id_column_name in self._data and self._data[self.id_column_name]) else False
|
|
116
120
|
|
|
117
121
|
@property
|
|
118
|
-
def data(self):
|
|
122
|
+
def data(self: Self):
|
|
119
123
|
return self._data
|
|
120
124
|
|
|
121
125
|
@data.setter
|
|
122
|
-
def data(self, data):
|
|
126
|
+
def data(self: Self, data) -> None:
|
|
123
127
|
self._data = {} if data is None else data
|
|
124
128
|
|
|
125
|
-
def save(self, data, columns=None):
|
|
129
|
+
def save(self: Self, data, columns=None) -> bool:
|
|
126
130
|
"""
|
|
127
131
|
Save data to the database and update the model!
|
|
128
132
|
|
|
@@ -168,7 +172,7 @@ class Model(Models):
|
|
|
168
172
|
|
|
169
173
|
return True
|
|
170
174
|
|
|
171
|
-
def is_changing(self, key, data):
|
|
175
|
+
def is_changing(self: Self, key, data) -> bool:
|
|
172
176
|
"""
|
|
173
177
|
Returns True/False to denote if the given column is being modified by the active save operation
|
|
174
178
|
|
|
@@ -184,7 +188,7 @@ class Model(Models):
|
|
|
184
188
|
|
|
185
189
|
return self.__getattr__(key) != data[key]
|
|
186
190
|
|
|
187
|
-
def latest(self, key, data):
|
|
191
|
+
def latest(self: Self, key, data):
|
|
188
192
|
"""
|
|
189
193
|
Returns the 'latest' value for a column during the save operation
|
|
190
194
|
|
|
@@ -198,7 +202,7 @@ class Model(Models):
|
|
|
198
202
|
return data[key]
|
|
199
203
|
return self.__getattr__(key)
|
|
200
204
|
|
|
201
|
-
def was_changed(self, key):
|
|
205
|
+
def was_changed(self: Self, key) -> bool:
|
|
202
206
|
"""Returns True/False to denote if a column was changed in the last save"""
|
|
203
207
|
if self._previous_data is None:
|
|
204
208
|
raise ValueError("was_changed was called before a save was finished - you must save something first")
|
|
@@ -221,10 +225,10 @@ class Model(Models):
|
|
|
221
225
|
return old_value != new_value
|
|
222
226
|
return not columns[key].values_match(old_value, new_value)
|
|
223
227
|
|
|
224
|
-
def previous_value(self, key):
|
|
228
|
+
def previous_value(self: Self, key):
|
|
225
229
|
return self.get_transformed_from_data(key, self._previous_data, cache=False, check_providers=False, silent=True)
|
|
226
230
|
|
|
227
|
-
def delete(self, except_if_not_exists=True):
|
|
231
|
+
def delete(self: Self, except_if_not_exists=True) -> bool:
|
|
228
232
|
if not self.exists:
|
|
229
233
|
if except_if_not_exists:
|
|
230
234
|
raise ValueError("Cannot delete model that already exists")
|
|
@@ -240,7 +244,7 @@ class Model(Models):
|
|
|
240
244
|
self.post_delete()
|
|
241
245
|
return True
|
|
242
246
|
|
|
243
|
-
def columns_pre_save(self, data, columns):
|
|
247
|
+
def columns_pre_save(self: Self, data, columns):
|
|
244
248
|
"""Uses the column information present in the model to make any necessary changes before saving"""
|
|
245
249
|
for column in columns.values():
|
|
246
250
|
data = column.pre_save(data, self)
|
|
@@ -258,7 +262,7 @@ class Model(Models):
|
|
|
258
262
|
"""
|
|
259
263
|
return data
|
|
260
264
|
|
|
261
|
-
def columns_to_backend(self, data, columns):
|
|
265
|
+
def columns_to_backend(self: Self, data, columns):
|
|
262
266
|
backend_data = {**data}
|
|
263
267
|
temporary_data = {}
|
|
264
268
|
for column in columns.values():
|
|
@@ -275,10 +279,10 @@ class Model(Models):
|
|
|
275
279
|
|
|
276
280
|
return [backend_data, temporary_data]
|
|
277
281
|
|
|
278
|
-
def to_backend(self, data, columns):
|
|
282
|
+
def to_backend(self: Self, data, columns):
|
|
279
283
|
return data
|
|
280
284
|
|
|
281
|
-
def columns_post_save(self, data, id, columns):
|
|
285
|
+
def columns_post_save(self: Self, data, id, columns):
|
|
282
286
|
"""Uses the column information present in the model to make additional changes as needed after saving"""
|
|
283
287
|
for column in columns.values():
|
|
284
288
|
data = column.post_save(data, self, id)
|
|
@@ -288,12 +292,12 @@ class Model(Models):
|
|
|
288
292
|
)
|
|
289
293
|
return data
|
|
290
294
|
|
|
291
|
-
def columns_save_finished(self, columns):
|
|
295
|
+
def columns_save_finished(self: Self, columns):
|
|
292
296
|
"""Calls the save_finished method on all of our columns"""
|
|
293
297
|
for column in columns.values():
|
|
294
298
|
column.save_finished(self)
|
|
295
299
|
|
|
296
|
-
def post_save(self, data, id):
|
|
300
|
+
def post_save(self: Self, data, id):
|
|
297
301
|
"""
|
|
298
302
|
A hook to extend so you can provide additional pre-save logic as needed
|
|
299
303
|
|
|
@@ -302,7 +306,7 @@ class Model(Models):
|
|
|
302
306
|
"""
|
|
303
307
|
pass
|
|
304
308
|
|
|
305
|
-
def pre_save(self, data):
|
|
309
|
+
def pre_save(self: Self, data):
|
|
306
310
|
"""
|
|
307
311
|
A hook to extend so you can provide additional pre-save logic as needed
|
|
308
312
|
|
|
@@ -310,7 +314,7 @@ class Model(Models):
|
|
|
310
314
|
"""
|
|
311
315
|
return data
|
|
312
316
|
|
|
313
|
-
def save_finished(self):
|
|
317
|
+
def save_finished(self: Self):
|
|
314
318
|
"""
|
|
315
319
|
A hook to extend so you can provide additional logic after a save operation has fully completed
|
|
316
320
|
|
|
@@ -320,29 +324,29 @@ class Model(Models):
|
|
|
320
324
|
"""
|
|
321
325
|
pass
|
|
322
326
|
|
|
323
|
-
def columns_pre_delete(self, columns):
|
|
327
|
+
def columns_pre_delete(self: Self, columns):
|
|
324
328
|
"""Uses the column information present in the model to make any necessary changes before deleting"""
|
|
325
329
|
for column in columns.values():
|
|
326
330
|
column.pre_delete(self)
|
|
327
331
|
|
|
328
|
-
def pre_delete(self):
|
|
332
|
+
def pre_delete(self: Self):
|
|
329
333
|
"""
|
|
330
334
|
A hook to extend so you can provide additional pre-delete logic as needed
|
|
331
335
|
"""
|
|
332
336
|
pass
|
|
333
337
|
|
|
334
|
-
def columns_post_delete(self, columns):
|
|
338
|
+
def columns_post_delete(self: Self, columns):
|
|
335
339
|
"""Uses the column information present in the model to make any necessary changes after deleting"""
|
|
336
340
|
for column in columns.values():
|
|
337
341
|
column.post_delete(self)
|
|
338
342
|
|
|
339
|
-
def post_delete(self):
|
|
343
|
+
def post_delete(self: Self):
|
|
340
344
|
"""
|
|
341
345
|
A hook to extend so you can provide additional post-delete logic as needed
|
|
342
346
|
"""
|
|
343
347
|
pass
|
|
344
348
|
|
|
345
|
-
def where_for_request(self, models, routing_data, authorization_data, input_output, overrides=None):
|
|
349
|
+
def where_for_request(self: Self, models, routing_data, authorization_data, input_output, overrides=None):
|
|
346
350
|
"""
|
|
347
351
|
A hook to automatically apply filtering whenever the model makes an appearance in a get/update/list/search handler.
|
|
348
352
|
"""
|
clearskies/models.py
CHANGED
|
@@ -47,30 +47,30 @@ class Models(ABC, ConditionParser):
|
|
|
47
47
|
self.query_select_all = True
|
|
48
48
|
|
|
49
49
|
@abstractmethod
|
|
50
|
-
def model_class(self):
|
|
50
|
+
def model_class(self: Self) -> type[Self]:
|
|
51
51
|
"""Return the model class that this models object will find/return instances of"""
|
|
52
52
|
pass
|
|
53
53
|
|
|
54
|
-
def clone(self) -> Self:
|
|
54
|
+
def clone(self: Self) -> Self:
|
|
55
55
|
clone = self.blank()
|
|
56
56
|
clone.query_configuration = self.query_configuration
|
|
57
57
|
return clone
|
|
58
58
|
|
|
59
|
-
def blank(self) -> Self:
|
|
59
|
+
def blank(self: Self) -> Self:
|
|
60
60
|
return self._build_model()
|
|
61
61
|
|
|
62
|
-
def get_table_name(self) -> str:
|
|
62
|
+
def get_table_name(self: Self) -> str:
|
|
63
63
|
if self._table_name is None:
|
|
64
64
|
self._table_name = self.model_class().table_name()
|
|
65
65
|
return self._table_name
|
|
66
66
|
|
|
67
|
-
def get_id_column_name(self) -> str:
|
|
67
|
+
def get_id_column_name(self: Self) -> str:
|
|
68
68
|
if self._id_column_name is None:
|
|
69
69
|
self._id_column_name = self.empty_model().id_column_name
|
|
70
70
|
return self._id_column_name
|
|
71
71
|
|
|
72
72
|
@property
|
|
73
|
-
def query_configuration(self) -> Dict[str, Any]:
|
|
73
|
+
def query_configuration(self: Self) -> Dict[str, Any]:
|
|
74
74
|
return {
|
|
75
75
|
"wheres": [*self.query_wheres],
|
|
76
76
|
"sorts": [*self.query_sorts],
|
|
@@ -85,7 +85,7 @@ class Models(ABC, ConditionParser):
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
@query_configuration.setter
|
|
88
|
-
def query_configuration(self, configuration: Dict[str, Any]):
|
|
88
|
+
def query_configuration(self: Self, configuration: Dict[str, Any]):
|
|
89
89
|
self.query_wheres = configuration["wheres"]
|
|
90
90
|
self.query_sorts = configuration["sorts"]
|
|
91
91
|
self.query_group_by_column = configuration["group_by_column"]
|
|
@@ -97,34 +97,34 @@ class Models(ABC, ConditionParser):
|
|
|
97
97
|
self._model_columns = configuration["model_columns"]
|
|
98
98
|
|
|
99
99
|
@property
|
|
100
|
-
def model_columns(self):
|
|
100
|
+
def model_columns(self: Self):
|
|
101
101
|
if self._model_columns is None:
|
|
102
102
|
self._model_columns = self.empty_model().columns()
|
|
103
103
|
return self._model_columns
|
|
104
104
|
|
|
105
|
-
def select(self, selects) -> Self:
|
|
105
|
+
def select(self: Self, selects) -> Self:
|
|
106
106
|
return self.clone().select_in_place(selects)
|
|
107
107
|
|
|
108
|
-
def select_in_place(self, selects) -> Self:
|
|
108
|
+
def select_in_place(self: Self, selects) -> Self:
|
|
109
109
|
self.query_selects.append(selects)
|
|
110
110
|
self.must_rexecute = True
|
|
111
111
|
self._next_page_data = None
|
|
112
112
|
return self
|
|
113
113
|
|
|
114
|
-
def select_all(self, select_all=True) -> Self:
|
|
114
|
+
def select_all(self: Self, select_all=True) -> Self:
|
|
115
115
|
return self.clone().select_all_in_place(select_all=select_all)
|
|
116
116
|
|
|
117
|
-
def select_all_in_place(self, select_all=True) -> Self:
|
|
117
|
+
def select_all_in_place(self: Self, select_all=True) -> Self:
|
|
118
118
|
self.query_select_all = select_all
|
|
119
119
|
self.must_rexecute = True
|
|
120
120
|
self._next_page_data = None
|
|
121
121
|
return self
|
|
122
122
|
|
|
123
|
-
def where(self, where: str) -> Self:
|
|
123
|
+
def where(self: Self, where: str) -> Self:
|
|
124
124
|
"""Adds the given condition to the query and returns a new Models object"""
|
|
125
125
|
return self.clone().where_in_place(where)
|
|
126
126
|
|
|
127
|
-
def where_in_place(self, where: str) -> Self:
|
|
127
|
+
def where_in_place(self: Self, where: str) -> Self:
|
|
128
128
|
"""Adds the given condition to the query for the current Models object"""
|
|
129
129
|
condition = self.parse_condition(where)
|
|
130
130
|
self._validate_column(condition["column"], "filter", table=condition["table"])
|
|
@@ -134,17 +134,17 @@ class Models(ABC, ConditionParser):
|
|
|
134
134
|
self.must_recount = True
|
|
135
135
|
return self
|
|
136
136
|
|
|
137
|
-
def join(self, join: str) -> Self:
|
|
137
|
+
def join(self: Self, join: str) -> Self:
|
|
138
138
|
return self.clone().join_in_place(join)
|
|
139
139
|
|
|
140
|
-
def join_in_place(self, join: str) -> Self:
|
|
140
|
+
def join_in_place(self: Self, join: str) -> Self:
|
|
141
141
|
self.query_joins.append(self.parse_join(join))
|
|
142
142
|
self.must_rexecute = True
|
|
143
143
|
self._next_page_data = None
|
|
144
144
|
self.must_recount = True
|
|
145
145
|
return self
|
|
146
146
|
|
|
147
|
-
def is_joined(self, table_name, alias=None):
|
|
147
|
+
def is_joined(self: Self, table_name, alias=None):
|
|
148
148
|
for join in self.query_joins:
|
|
149
149
|
if join["table"] != table_name:
|
|
150
150
|
continue
|
|
@@ -155,10 +155,10 @@ class Models(ABC, ConditionParser):
|
|
|
155
155
|
return join["alias"] if join["alias"] else join["table"]
|
|
156
156
|
return False
|
|
157
157
|
|
|
158
|
-
def group_by(self, group_column: str) -> Self:
|
|
158
|
+
def group_by(self: Self, group_column: str) -> Self:
|
|
159
159
|
return self.clone().group_by_in_place(group_column)
|
|
160
160
|
|
|
161
|
-
def group_by_in_place(self, group_column: str) -> Self:
|
|
161
|
+
def group_by_in_place(self: Self, group_column: str) -> Self:
|
|
162
162
|
self._validate_column(group_column, "group")
|
|
163
163
|
self.query_group_by_column = group_column
|
|
164
164
|
self.must_rexecute = True
|
|
@@ -167,7 +167,7 @@ class Models(ABC, ConditionParser):
|
|
|
167
167
|
return self
|
|
168
168
|
|
|
169
169
|
def sort_by(
|
|
170
|
-
self,
|
|
170
|
+
self: Self,
|
|
171
171
|
primary_column,
|
|
172
172
|
primary_direction,
|
|
173
173
|
primary_table=None,
|
|
@@ -185,7 +185,7 @@ class Models(ABC, ConditionParser):
|
|
|
185
185
|
)
|
|
186
186
|
|
|
187
187
|
def sort_by_in_place(
|
|
188
|
-
self,
|
|
188
|
+
self: Self,
|
|
189
189
|
primary_column,
|
|
190
190
|
primary_direction,
|
|
191
191
|
primary_table=None,
|
|
@@ -205,7 +205,7 @@ class Models(ABC, ConditionParser):
|
|
|
205
205
|
self._next_page_data = None
|
|
206
206
|
return self
|
|
207
207
|
|
|
208
|
-
def _normalize_and_validate_sort(self, sort):
|
|
208
|
+
def _normalize_and_validate_sort(self: Self, sort):
|
|
209
209
|
if "column" not in sort or not sort["column"]:
|
|
210
210
|
raise ValueError("Missing 'column' for sort")
|
|
211
211
|
if "direction" not in sort or not sort["direction"]:
|
|
@@ -218,7 +218,7 @@ class Models(ABC, ConditionParser):
|
|
|
218
218
|
# down the line we may ask the model class what columns we can sort on, but we're good for now
|
|
219
219
|
return {"column": sort["column"], "direction": sort["direction"], "table": sort.get("table")}
|
|
220
220
|
|
|
221
|
-
def _validate_column(self, column_name, action, table=None):
|
|
221
|
+
def _validate_column(self: Self, column_name, action, table=None):
|
|
222
222
|
"""
|
|
223
223
|
Down the line we may use the model configuration to check what columns are valid sort/group/search targets
|
|
224
224
|
"""
|
|
@@ -246,19 +246,19 @@ class Models(ABC, ConditionParser):
|
|
|
246
246
|
+ "to your model definition"
|
|
247
247
|
)
|
|
248
248
|
|
|
249
|
-
def limit(self, limit) -> Self:
|
|
249
|
+
def limit(self: Self, limit) -> Self:
|
|
250
250
|
return self.clone().limit_in_place(limit)
|
|
251
251
|
|
|
252
|
-
def limit_in_place(self, limit) -> Self:
|
|
252
|
+
def limit_in_place(self: Self, limit) -> Self:
|
|
253
253
|
self.query_limit = limit
|
|
254
254
|
self.must_rexecute = True
|
|
255
255
|
self._next_page_data = None
|
|
256
256
|
return self
|
|
257
257
|
|
|
258
|
-
def pagination(self, **kwargs) -> Self:
|
|
258
|
+
def pagination(self: Self, **kwargs) -> Self:
|
|
259
259
|
return self.clone().pagination_in_place(**kwargs)
|
|
260
260
|
|
|
261
|
-
def pagination_in_place(self, **kwargs) -> Self:
|
|
261
|
+
def pagination_in_place(self: Self, **kwargs) -> Self:
|
|
262
262
|
error = self._backend.validate_pagination_kwargs(kwargs, str)
|
|
263
263
|
if error:
|
|
264
264
|
raise ValueError(
|
|
@@ -270,17 +270,17 @@ class Models(ABC, ConditionParser):
|
|
|
270
270
|
self._next_page_data = None
|
|
271
271
|
return self
|
|
272
272
|
|
|
273
|
-
def find(self, where: str) -> Self:
|
|
273
|
+
def find(self: Self, where: str) -> Self:
|
|
274
274
|
"""Returns the first model where condition"""
|
|
275
275
|
return self.clone().where(where).first()
|
|
276
276
|
|
|
277
|
-
def __len__(self):
|
|
277
|
+
def __len__(self: Self):
|
|
278
278
|
if self.must_recount:
|
|
279
279
|
self.count = self._backend.count(self.query_configuration, self.empty_model())
|
|
280
280
|
self.must_recount = False
|
|
281
281
|
return self.count
|
|
282
282
|
|
|
283
|
-
def __iter__(self) -> Iterator[Self]:
|
|
283
|
+
def __iter__(self: Self) -> Iterator[Self]:
|
|
284
284
|
self._next_page_data = {}
|
|
285
285
|
raw_rows = self._backend.records(
|
|
286
286
|
self.query_configuration,
|
|
@@ -290,7 +290,7 @@ class Models(ABC, ConditionParser):
|
|
|
290
290
|
models = iter([self.model(row) for row in raw_rows])
|
|
291
291
|
return models
|
|
292
292
|
|
|
293
|
-
def paginate_all(self) -> List[Self]:
|
|
293
|
+
def paginate_all(self: Self) -> List[Self]:
|
|
294
294
|
next_models = self.clone()
|
|
295
295
|
results = list(next_models.__iter__())
|
|
296
296
|
next_page_data = next_models.next_page_data()
|
|
@@ -300,51 +300,51 @@ class Models(ABC, ConditionParser):
|
|
|
300
300
|
next_page_data = next_models.next_page_data()
|
|
301
301
|
return results
|
|
302
302
|
|
|
303
|
-
def model(self, data) -> Self:
|
|
303
|
+
def model(self: Self, data) -> Self:
|
|
304
304
|
model = self._build_model()
|
|
305
305
|
model.data = data
|
|
306
306
|
return model
|
|
307
307
|
|
|
308
|
-
def _build_model(self) -> Self:
|
|
308
|
+
def _build_model(self: Self) -> Self:
|
|
309
309
|
model_class = self.model_class()
|
|
310
310
|
return model_class(self._backend, self._columns)
|
|
311
311
|
|
|
312
|
-
def empty_model(self) -> Self:
|
|
312
|
+
def empty_model(self: Self) -> Self:
|
|
313
313
|
return self.model({})
|
|
314
314
|
|
|
315
|
-
def create(self, data: Dict[str, Any]) -> Self:
|
|
315
|
+
def create(self: Self, data: Dict[str, Any]) -> Self:
|
|
316
316
|
empty = self.empty_model()
|
|
317
317
|
empty.save(data)
|
|
318
318
|
return empty
|
|
319
319
|
|
|
320
|
-
def first(self) -> Self:
|
|
320
|
+
def first(self: Self) -> Self:
|
|
321
321
|
iter = self.__iter__()
|
|
322
322
|
try:
|
|
323
323
|
return iter.__next__()
|
|
324
324
|
except StopIteration:
|
|
325
325
|
return self.empty_model()
|
|
326
326
|
|
|
327
|
-
def columns(self, overrides=None):
|
|
327
|
+
def columns(self: Self, overrides=None):
|
|
328
328
|
model = self.model({})
|
|
329
329
|
return model.columns(overrides=None)
|
|
330
330
|
|
|
331
|
-
def raw_columns_configuration(self):
|
|
331
|
+
def raw_columns_configuration(self: Self):
|
|
332
332
|
return self.model({}).all_columns()
|
|
333
333
|
|
|
334
|
-
def allowed_pagination_keys(self) -> List[str]:
|
|
334
|
+
def allowed_pagination_keys(self: Self) -> List[str]:
|
|
335
335
|
return self._backend.allowed_pagination_keys()
|
|
336
336
|
|
|
337
337
|
def validate_pagination_kwargs(self, kwargs: Dict[str, Any], case_mapping: Callable) -> str:
|
|
338
338
|
return self._backend.validate_pagination_kwargs(kwargs, case_mapping)
|
|
339
339
|
|
|
340
|
-
def next_page_data(self):
|
|
340
|
+
def next_page_data(self: Self):
|
|
341
341
|
return self._next_page_data
|
|
342
342
|
|
|
343
|
-
def documentation_pagination_next_page_response(self, case_mapping: Callable) -> List[Any]:
|
|
343
|
+
def documentation_pagination_next_page_response(self: Self, case_mapping: Callable) -> List[Any]:
|
|
344
344
|
return self._backend.documentation_pagination_next_page_response(case_mapping)
|
|
345
345
|
|
|
346
|
-
def documentation_pagination_next_page_example(self, case_mapping: Callable) -> Dict[str, Any]:
|
|
346
|
+
def documentation_pagination_next_page_example(self: Self, case_mapping: Callable) -> Dict[str, Any]:
|
|
347
347
|
return self._backend.documentation_pagination_next_page_example(case_mapping)
|
|
348
348
|
|
|
349
|
-
def documentation_pagination_parameters(self, case_mapping: Callable) -> List[Tuple[Any]]:
|
|
349
|
+
def documentation_pagination_parameters(self: Self, case_mapping: Callable) -> List[Tuple[Any]]:
|
|
350
350
|
return self._backend.documentation_pagination_parameters(case_mapping)
|
|
File without changes
|
|
File without changes
|