appier 1.31.4__py2.py3-none-any.whl → 1.32.0__py2.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.
- appier/__init__.py +333 -52
- appier/amqp.py +29 -30
- appier/api.py +214 -212
- appier/asgi.py +54 -55
- appier/async_neo.py +46 -35
- appier/async_old.py +55 -42
- appier/asynchronous.py +7 -13
- appier/base.py +1762 -1429
- appier/bus.py +51 -52
- appier/cache.py +99 -84
- appier/common.py +9 -11
- appier/component.py +17 -19
- appier/compress.py +25 -28
- appier/config.py +96 -73
- appier/controller.py +9 -15
- appier/crypt.py +25 -21
- appier/data.py +73 -57
- appier/defines.py +191 -226
- appier/exceptions.py +103 -63
- appier/execution.py +94 -88
- appier/export.py +90 -88
- appier/extra.py +6 -13
- appier/extra_neo.py +8 -11
- appier/extra_old.py +18 -16
- appier/geo.py +57 -47
- appier/git.py +101 -90
- appier/graph.py +23 -24
- appier/http.py +520 -398
- appier/legacy.py +373 -180
- appier/log.py +90 -97
- appier/meta.py +42 -42
- appier/mock.py +32 -34
- appier/model.py +793 -681
- appier/model_a.py +208 -183
- appier/mongo.py +183 -107
- appier/observer.py +39 -31
- appier/part.py +23 -24
- appier/preferences.py +44 -47
- appier/queuing.py +78 -96
- appier/redisdb.py +40 -35
- appier/request.py +227 -175
- appier/scheduler.py +13 -18
- appier/serialize.py +37 -31
- appier/session.py +161 -147
- appier/settings.py +2 -11
- appier/smtp.py +53 -49
- appier/storage.py +39 -33
- appier/structures.py +50 -45
- appier/test/__init__.py +2 -11
- appier/test/base.py +111 -108
- appier/test/cache.py +28 -35
- appier/test/config.py +10 -19
- appier/test/crypt.py +3 -12
- appier/test/data.py +3 -12
- appier/test/exceptions.py +8 -17
- appier/test/export.py +16 -33
- appier/test/graph.py +27 -60
- appier/test/http.py +42 -54
- appier/test/legacy.py +20 -30
- appier/test/log.py +14 -35
- appier/test/mock.py +27 -123
- appier/test/model.py +79 -91
- appier/test/part.py +5 -14
- appier/test/preferences.py +5 -13
- appier/test/queuing.py +29 -37
- appier/test/request.py +61 -73
- appier/test/serialize.py +12 -23
- appier/test/session.py +10 -19
- appier/test/smtp.py +8 -14
- appier/test/structures.py +20 -24
- appier/test/typesf.py +14 -28
- appier/test/util.py +480 -438
- appier/typesf.py +251 -171
- appier/util.py +578 -407
- appier/validation.py +280 -143
- {appier-1.31.4.dist-info → appier-1.32.0.dist-info}/METADATA +6 -1
- appier-1.32.0.dist-info/RECORD +86 -0
- appier-1.31.4.dist-info/RECORD +0 -86
- {appier-1.31.4.dist-info → appier-1.32.0.dist-info}/LICENSE +0 -0
- {appier-1.31.4.dist-info → appier-1.32.0.dist-info}/WHEEL +0 -0
- {appier-1.31.4.dist-info → appier-1.32.0.dist-info}/top_level.txt +0 -0
appier/model_a.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
3
|
|
|
4
4
|
# Hive Appier Framework
|
|
5
|
-
# Copyright (c) 2008-
|
|
5
|
+
# Copyright (c) 2008-2024 Hive Solutions Lda.
|
|
6
6
|
#
|
|
7
7
|
# This file is part of Hive Appier Framework.
|
|
8
8
|
#
|
|
@@ -22,16 +22,7 @@
|
|
|
22
22
|
__author__ = "João Magalhães <joamag@hive.pt>"
|
|
23
23
|
""" The author(s) of the module """
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
""" The version of the module """
|
|
27
|
-
|
|
28
|
-
__revision__ = "$LastChangedRevision$"
|
|
29
|
-
""" The revision number of the module """
|
|
30
|
-
|
|
31
|
-
__date__ = "$LastChangedDate$"
|
|
32
|
-
""" The last change date of the module """
|
|
33
|
-
|
|
34
|
-
__copyright__ = "Copyright (c) 2008-2022 Hive Solutions Lda."
|
|
25
|
+
__copyright__ = "Copyright (c) 2008-2024 Hive Solutions Lda."
|
|
35
26
|
""" The copyright for the module """
|
|
36
27
|
|
|
37
28
|
__license__ = "Apache License, Version 2.0"
|
|
@@ -43,201 +34,218 @@ from . import common
|
|
|
43
34
|
from . import legacy
|
|
44
35
|
from . import exceptions
|
|
45
36
|
|
|
46
|
-
class ModelAsync(object):
|
|
47
37
|
|
|
38
|
+
class ModelAsync(object):
|
|
48
39
|
@classmethod
|
|
49
40
|
async def get_a(cls, *args, **kwargs):
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
(
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
41
|
+
(
|
|
42
|
+
fields,
|
|
43
|
+
eager,
|
|
44
|
+
eager_l,
|
|
45
|
+
map,
|
|
46
|
+
rules,
|
|
47
|
+
meta,
|
|
48
|
+
build,
|
|
49
|
+
fill,
|
|
50
|
+
resolve_a,
|
|
51
|
+
skip,
|
|
52
|
+
limit,
|
|
53
|
+
sort,
|
|
54
|
+
raise_e,
|
|
55
|
+
) = cls._get_attrs(
|
|
56
|
+
kwargs,
|
|
57
|
+
(
|
|
58
|
+
("fields", None),
|
|
59
|
+
("eager", None),
|
|
60
|
+
("eager_l", None),
|
|
61
|
+
("map", False),
|
|
62
|
+
("rules", True),
|
|
63
|
+
("meta", False),
|
|
64
|
+
("build", True),
|
|
65
|
+
("fill", True),
|
|
66
|
+
("resolve_a", None),
|
|
67
|
+
("skip", 0),
|
|
68
|
+
("limit", 0),
|
|
69
|
+
("sort", None),
|
|
70
|
+
("raise_e", True),
|
|
71
|
+
),
|
|
72
|
+
)
|
|
77
73
|
|
|
78
74
|
# in case there's a sort field and the safe search mode is enabled
|
|
79
75
|
# we must add sorting by the `_id` field so that the retrieval is
|
|
80
76
|
# considered to be deterministic, otherwise some DB implementations
|
|
81
77
|
# will not respect the same sorting sequence across different calls
|
|
82
78
|
if sort and (skip or limit):
|
|
83
|
-
if not isinstance(sort, list):
|
|
79
|
+
if not isinstance(sort, list):
|
|
80
|
+
sort = list(sort)
|
|
84
81
|
sort.append(["_id", 1])
|
|
85
82
|
|
|
86
|
-
if eager_l == None:
|
|
87
|
-
|
|
88
|
-
if
|
|
89
|
-
|
|
83
|
+
if eager_l == None:
|
|
84
|
+
eager_l = map
|
|
85
|
+
if resolve_a == None:
|
|
86
|
+
resolve_a = map
|
|
87
|
+
if eager_l:
|
|
88
|
+
eager = cls._eager_b(eager)
|
|
89
|
+
fields = cls._sniff(fields, rules=rules)
|
|
90
90
|
collection = cls._collection_a()
|
|
91
91
|
model = await collection.find_one(
|
|
92
|
-
kwargs,
|
|
93
|
-
fields,
|
|
94
|
-
skip = skip,
|
|
95
|
-
limit = limit,
|
|
96
|
-
sort = sort
|
|
92
|
+
kwargs, fields, skip=skip, limit=limit, sort=sort
|
|
97
93
|
)
|
|
98
94
|
if not model and raise_e:
|
|
99
95
|
is_devel = common.is_devel()
|
|
100
|
-
if is_devel:
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
96
|
+
if is_devel:
|
|
97
|
+
message = "%s not found for %s" % (cls.__name__, str(kwargs))
|
|
98
|
+
else:
|
|
99
|
+
message = "%s not found" % cls.__name__
|
|
100
|
+
raise exceptions.NotFoundError(message=message)
|
|
101
|
+
if not model and not raise_e:
|
|
102
|
+
return model
|
|
104
103
|
cls.types(model)
|
|
105
|
-
if fill:
|
|
106
|
-
|
|
107
|
-
if
|
|
108
|
-
|
|
109
|
-
|
|
104
|
+
if fill:
|
|
105
|
+
cls.fill(model, safe=True)
|
|
106
|
+
if build:
|
|
107
|
+
cls.build(model, map=map, rules=rules, meta=meta)
|
|
108
|
+
if eager:
|
|
109
|
+
model = cls._eager(model, eager, map=map)
|
|
110
|
+
if resolve_a:
|
|
111
|
+
model = cls._resolve_all(model, resolve=False)
|
|
112
|
+
return model if map else cls.old(model=model, safe=False)
|
|
110
113
|
|
|
111
114
|
@classmethod
|
|
112
115
|
async def find_a(cls, *args, **kwargs):
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
(
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
116
|
+
(
|
|
117
|
+
fields,
|
|
118
|
+
eager,
|
|
119
|
+
eager_l,
|
|
120
|
+
map,
|
|
121
|
+
rules,
|
|
122
|
+
meta,
|
|
123
|
+
build,
|
|
124
|
+
fill,
|
|
125
|
+
resolve_a,
|
|
126
|
+
skip,
|
|
127
|
+
limit,
|
|
128
|
+
sort,
|
|
129
|
+
raise_e,
|
|
130
|
+
) = cls._get_attrs(
|
|
131
|
+
kwargs,
|
|
132
|
+
(
|
|
133
|
+
("fields", None),
|
|
134
|
+
("eager", None),
|
|
135
|
+
("eager_l", False),
|
|
136
|
+
("map", False),
|
|
137
|
+
("rules", True),
|
|
138
|
+
("meta", False),
|
|
139
|
+
("build", True),
|
|
140
|
+
("fill", True),
|
|
141
|
+
("resolve_a", None),
|
|
142
|
+
("skip", 0),
|
|
143
|
+
("limit", 0),
|
|
144
|
+
("sort", None),
|
|
145
|
+
("raise_e", False),
|
|
146
|
+
),
|
|
147
|
+
)
|
|
140
148
|
|
|
141
149
|
# in case there's a sort field and the safe search mode is enabled
|
|
142
150
|
# we must add sorting by the `_id` field so that the search is
|
|
143
151
|
# considered to be deterministic, otherwise some DB implementations
|
|
144
152
|
# will not respect the same sorting sequence across different calls
|
|
145
153
|
if sort and (skip or limit):
|
|
146
|
-
if not isinstance(sort, list):
|
|
154
|
+
if not isinstance(sort, list):
|
|
155
|
+
sort = list(sort)
|
|
147
156
|
sort.append(["_id", 1])
|
|
148
157
|
|
|
149
|
-
if resolve_a == None:
|
|
150
|
-
|
|
158
|
+
if resolve_a == None:
|
|
159
|
+
resolve_a = map
|
|
160
|
+
if eager_l:
|
|
161
|
+
eager = cls._eager_b(eager)
|
|
151
162
|
|
|
152
163
|
cls._find_s(kwargs)
|
|
153
164
|
cls._find_d(kwargs)
|
|
154
165
|
|
|
155
|
-
fields = cls._sniff(fields, rules
|
|
166
|
+
fields = cls._sniff(fields, rules=rules)
|
|
156
167
|
collection = cls._collection_a()
|
|
157
|
-
models = collection.find(
|
|
158
|
-
kwargs,
|
|
159
|
-
fields,
|
|
160
|
-
skip = skip,
|
|
161
|
-
limit = limit,
|
|
162
|
-
sort = sort
|
|
163
|
-
)
|
|
168
|
+
models = collection.find(kwargs, fields, skip=skip, limit=limit, sort=sort)
|
|
164
169
|
if not models and raise_e:
|
|
165
170
|
is_devel = common.is_devel()
|
|
166
|
-
if is_devel:
|
|
167
|
-
|
|
168
|
-
|
|
171
|
+
if is_devel:
|
|
172
|
+
message = "%s not found for %s" % (cls.__name__, str(kwargs))
|
|
173
|
+
else:
|
|
174
|
+
message = "%s not found" % cls.__name__
|
|
175
|
+
raise exceptions.NotFoundError(message=message)
|
|
169
176
|
models = [cls.types(model) async for model in models]
|
|
170
|
-
if fill:
|
|
171
|
-
|
|
172
|
-
if
|
|
173
|
-
|
|
174
|
-
|
|
177
|
+
if fill:
|
|
178
|
+
models = [cls.fill(model, safe=True) for model in models]
|
|
179
|
+
if build:
|
|
180
|
+
[cls.build(model, map=map, rules=rules, meta=meta) for model in models]
|
|
181
|
+
if eager:
|
|
182
|
+
models = cls._eager(models, eager, map=map)
|
|
183
|
+
if resolve_a:
|
|
184
|
+
models = [cls._resolve_all(model, resolve=False) for model in models]
|
|
185
|
+
models = (
|
|
186
|
+
models if map else [cls.old(model=model, safe=False) for model in models]
|
|
187
|
+
)
|
|
175
188
|
return models
|
|
176
189
|
|
|
177
190
|
@classmethod
|
|
178
191
|
async def _increment_a(cls, name):
|
|
179
192
|
_name = cls._name() + ":" + name
|
|
180
|
-
store = cls._collection_a(name
|
|
193
|
+
store = cls._collection_a(name="counters")
|
|
181
194
|
value = await store.find_and_modify(
|
|
182
|
-
{
|
|
183
|
-
"_id" : _name
|
|
184
|
-
},
|
|
185
|
-
{
|
|
186
|
-
"$inc" : {
|
|
187
|
-
"seq" : 1
|
|
188
|
-
}
|
|
189
|
-
},
|
|
190
|
-
new = True,
|
|
191
|
-
upsert = True
|
|
195
|
+
{"_id": _name}, {"$inc": {"seq": 1}}, new=True, upsert=True
|
|
192
196
|
)
|
|
193
|
-
value = value or await store.find_one({
|
|
194
|
-
"_id" : _name
|
|
195
|
-
})
|
|
197
|
+
value = value or await store.find_one({"_id": _name})
|
|
196
198
|
return value["seq"]
|
|
197
199
|
|
|
198
200
|
async def save_a(
|
|
199
201
|
self,
|
|
200
|
-
validate
|
|
201
|
-
verify
|
|
202
|
-
is_new
|
|
203
|
-
increment_a
|
|
204
|
-
immutables_a
|
|
205
|
-
pre_validate
|
|
206
|
-
pre_save
|
|
207
|
-
pre_create
|
|
208
|
-
pre_update
|
|
209
|
-
post_validate
|
|
210
|
-
post_save
|
|
211
|
-
post_create
|
|
212
|
-
post_update
|
|
213
|
-
before_callbacks
|
|
214
|
-
after_callbacks
|
|
202
|
+
validate=True,
|
|
203
|
+
verify=True,
|
|
204
|
+
is_new=None,
|
|
205
|
+
increment_a=None,
|
|
206
|
+
immutables_a=None,
|
|
207
|
+
pre_validate=True,
|
|
208
|
+
pre_save=True,
|
|
209
|
+
pre_create=True,
|
|
210
|
+
pre_update=True,
|
|
211
|
+
post_validate=True,
|
|
212
|
+
post_save=True,
|
|
213
|
+
post_create=True,
|
|
214
|
+
post_update=True,
|
|
215
|
+
before_callbacks=[],
|
|
216
|
+
after_callbacks=[],
|
|
215
217
|
):
|
|
216
218
|
# ensures that the current instance is associated with
|
|
217
219
|
# a concrete model, ready to be persisted in database
|
|
218
|
-
if verify:
|
|
220
|
+
if verify:
|
|
221
|
+
self.assert_is_concrete()
|
|
219
222
|
|
|
220
223
|
# checks if the instance to be saved is a new instance
|
|
221
224
|
# or if this is an update operation and then determines
|
|
222
225
|
# series of default values taking that into account
|
|
223
|
-
if is_new == None:
|
|
224
|
-
|
|
225
|
-
if
|
|
226
|
+
if is_new == None:
|
|
227
|
+
is_new = self.is_new()
|
|
228
|
+
if increment_a == None:
|
|
229
|
+
increment_a = is_new
|
|
230
|
+
if immutables_a == None:
|
|
231
|
+
immutables_a = not is_new
|
|
226
232
|
|
|
227
233
|
# runs the validation process in the current model, this
|
|
228
234
|
# should ensure that the model is ready to be saved in the
|
|
229
235
|
# data source, without corruption of it, only run this process
|
|
230
236
|
# in case the validate flag is correctly set
|
|
231
237
|
validate and self._validate(
|
|
232
|
-
pre_validate
|
|
233
|
-
post_validate = post_validate
|
|
238
|
+
pre_validate=pre_validate, post_validate=post_validate
|
|
234
239
|
)
|
|
235
240
|
|
|
236
241
|
# calls the complete set of event handlers for the current
|
|
237
242
|
# save operation, this should trigger changes in the model
|
|
238
|
-
if pre_save:
|
|
239
|
-
|
|
240
|
-
if
|
|
243
|
+
if pre_save:
|
|
244
|
+
self.pre_save()
|
|
245
|
+
if pre_create and is_new:
|
|
246
|
+
self.pre_create()
|
|
247
|
+
if pre_update and not is_new:
|
|
248
|
+
self.pre_update()
|
|
241
249
|
|
|
242
250
|
# filters the values that are present in the current model
|
|
243
251
|
# so that only the valid ones are stored in, invalid values
|
|
@@ -247,37 +255,42 @@ class ModelAsync(object):
|
|
|
247
255
|
# any relation is loaded the reference value is returned instead
|
|
248
256
|
# of the loaded relation values (required for persistence)
|
|
249
257
|
model = await self._filter_a(
|
|
250
|
-
increment_a =
|
|
251
|
-
immutables_a = immutables_a,
|
|
252
|
-
normalize = True
|
|
258
|
+
increment_a=increment_a, immutables_a=immutables_a, normalize=True
|
|
253
259
|
)
|
|
254
260
|
|
|
255
261
|
# in case the current model is not new must create a new
|
|
256
262
|
# model instance and remove the main identifier from it
|
|
257
|
-
if not is_new:
|
|
263
|
+
if not is_new:
|
|
264
|
+
_model = copy.copy(model)
|
|
265
|
+
del _model["_id"]
|
|
258
266
|
|
|
259
267
|
# calls the complete set of callbacks that should be called
|
|
260
268
|
# before the concrete data store save operation
|
|
261
|
-
for callback in before_callbacks:
|
|
269
|
+
for callback in before_callbacks:
|
|
270
|
+
callback(self, model)
|
|
262
271
|
|
|
263
272
|
# retrieves the reference to the store object to be used and
|
|
264
273
|
# uses it to store the current model data
|
|
265
274
|
store = self._get_store_a()
|
|
266
275
|
if is_new:
|
|
267
276
|
await store.insert(model)
|
|
268
|
-
self.apply(model, safe_a
|
|
277
|
+
self.apply(model, safe_a=False)
|
|
269
278
|
else:
|
|
270
|
-
await store.update({"_id"
|
|
279
|
+
await store.update({"_id": model["_id"]}, {"$set": _model})
|
|
271
280
|
|
|
272
281
|
# calls the complete set of callbacks that should be called
|
|
273
282
|
# after the concrete data store save operation
|
|
274
|
-
for callback in after_callbacks:
|
|
283
|
+
for callback in after_callbacks:
|
|
284
|
+
callback(self, model)
|
|
275
285
|
|
|
276
286
|
# calls the post save event handlers in order to be able to
|
|
277
287
|
# execute appropriate post operations
|
|
278
|
-
if post_save:
|
|
279
|
-
|
|
280
|
-
if
|
|
288
|
+
if post_save:
|
|
289
|
+
self.post_save()
|
|
290
|
+
if post_create and is_new:
|
|
291
|
+
self.post_create()
|
|
292
|
+
if post_update and not is_new:
|
|
293
|
+
self.post_update()
|
|
281
294
|
|
|
282
295
|
# returns the instance that has just been used for the save
|
|
283
296
|
# operation, this may be used for chaining operations
|
|
@@ -285,28 +298,31 @@ class ModelAsync(object):
|
|
|
285
298
|
|
|
286
299
|
async def delete_a(
|
|
287
300
|
self,
|
|
288
|
-
verify
|
|
289
|
-
pre_delete
|
|
290
|
-
post_delete
|
|
291
|
-
before_callbacks
|
|
292
|
-
after_callbacks
|
|
301
|
+
verify=True,
|
|
302
|
+
pre_delete=True,
|
|
303
|
+
post_delete=True,
|
|
304
|
+
before_callbacks=[],
|
|
305
|
+
after_callbacks=[],
|
|
293
306
|
):
|
|
294
307
|
# ensures that the current instance is associated with
|
|
295
308
|
# a concrete model, ready to be persisted in database
|
|
296
|
-
if verify:
|
|
309
|
+
if verify:
|
|
310
|
+
self.assert_is_concrete()
|
|
297
311
|
|
|
298
312
|
# calls the complete set of event handlers for the current
|
|
299
313
|
# delete operation, this should trigger changes in the model
|
|
300
|
-
if pre_delete:
|
|
314
|
+
if pre_delete:
|
|
315
|
+
self.pre_delete()
|
|
301
316
|
|
|
302
317
|
# calls the complete set of callbacks that should be called
|
|
303
318
|
# before the concrete data store delete operation
|
|
304
|
-
for callback in before_callbacks:
|
|
319
|
+
for callback in before_callbacks:
|
|
320
|
+
callback(self)
|
|
305
321
|
|
|
306
322
|
# retrieves the reference to the store object to be able to
|
|
307
323
|
# execute the removal command for the current model
|
|
308
324
|
store = self._get_store_a()
|
|
309
|
-
await store.remove({"_id"
|
|
325
|
+
await store.remove({"_id": self._id})
|
|
310
326
|
|
|
311
327
|
# calls the underlying delete handler that may be used to extend
|
|
312
328
|
# the default delete functionality
|
|
@@ -314,29 +330,31 @@ class ModelAsync(object):
|
|
|
314
330
|
|
|
315
331
|
# calls the complete set of callbacks that should be called
|
|
316
332
|
# after the concrete data store delete operation
|
|
317
|
-
for callback in after_callbacks:
|
|
333
|
+
for callback in after_callbacks:
|
|
334
|
+
callback(self)
|
|
318
335
|
|
|
319
336
|
# calls the complete set of event handlers for the current
|
|
320
337
|
# delete operation, this should trigger changes in the model
|
|
321
|
-
if post_delete:
|
|
338
|
+
if post_delete:
|
|
339
|
+
self.post_delete()
|
|
322
340
|
|
|
323
341
|
async def reload_a(self, *args, **kwargs):
|
|
324
342
|
is_new = self.is_new()
|
|
325
|
-
if is_new:
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
343
|
+
if is_new:
|
|
344
|
+
raise exceptions.OperationalError(
|
|
345
|
+
message="Can't reload a new model entity", code=412
|
|
346
|
+
)
|
|
329
347
|
cls = self.__class__
|
|
330
|
-
return await cls.get_a(_id
|
|
348
|
+
return await cls.get_a(_id=self._id, *args, **kwargs)
|
|
331
349
|
|
|
332
350
|
async def _filter_a(
|
|
333
351
|
self,
|
|
334
|
-
increment_a
|
|
335
|
-
immutables_a
|
|
336
|
-
normalize
|
|
337
|
-
resolve
|
|
338
|
-
all
|
|
339
|
-
evaluator
|
|
352
|
+
increment_a=True,
|
|
353
|
+
immutables_a=False,
|
|
354
|
+
normalize=False,
|
|
355
|
+
resolve=False,
|
|
356
|
+
all=False,
|
|
357
|
+
evaluator="json_v",
|
|
340
358
|
):
|
|
341
359
|
# creates the model that will hold the "filtered" model
|
|
342
360
|
# with all the items that conform with the class specification
|
|
@@ -364,7 +382,8 @@ class ModelAsync(object):
|
|
|
364
382
|
# fields so that a new value is set on the model, note that if
|
|
365
383
|
# the increment apply is unset the increment operation is ignored
|
|
366
384
|
for name in increments:
|
|
367
|
-
if not increment_a:
|
|
385
|
+
if not increment_a:
|
|
386
|
+
continue
|
|
368
387
|
if name in self.model:
|
|
369
388
|
model[name] = cls._ensure_min(name, self.model[name])
|
|
370
389
|
else:
|
|
@@ -373,9 +392,11 @@ class ModelAsync(object):
|
|
|
373
392
|
# iterates over all the model items to filter the ones
|
|
374
393
|
# that are not valid for the current class context
|
|
375
394
|
for name, value in legacy.eager(self.model.items()):
|
|
376
|
-
if not name in definition:
|
|
377
|
-
|
|
378
|
-
|
|
395
|
+
if not name in definition:
|
|
396
|
+
continue
|
|
397
|
+
if immutables_a and name in immutables:
|
|
398
|
+
continue
|
|
399
|
+
value = self._evaluate(name, value, evaluator=evaluator)
|
|
379
400
|
model[name] = value
|
|
380
401
|
|
|
381
402
|
# in case the normalize flag is set must iterate over all
|
|
@@ -384,8 +405,10 @@ class ModelAsync(object):
|
|
|
384
405
|
# the normal value that would prevent normalization
|
|
385
406
|
if normalize:
|
|
386
407
|
for name, value in legacy.eager(self.model.items()):
|
|
387
|
-
if not name in definition:
|
|
388
|
-
|
|
408
|
+
if not name in definition:
|
|
409
|
+
continue
|
|
410
|
+
if not hasattr(value, "ref_v"):
|
|
411
|
+
continue
|
|
389
412
|
model[name] = value.ref_v()
|
|
390
413
|
|
|
391
414
|
# in case the resolution flag is set, it means that a recursive
|
|
@@ -395,7 +418,8 @@ class ModelAsync(object):
|
|
|
395
418
|
# may imply access to the base data source
|
|
396
419
|
if resolve:
|
|
397
420
|
for name, value in legacy.eager(self.model.items()):
|
|
398
|
-
if not name in definition:
|
|
421
|
+
if not name in definition:
|
|
422
|
+
continue
|
|
399
423
|
model[name] = cls._resolve(name, value)
|
|
400
424
|
|
|
401
425
|
# in case the all flag is set the extra fields (not present
|
|
@@ -404,7 +428,8 @@ class ModelAsync(object):
|
|
|
404
428
|
# present in the base map of the current instance
|
|
405
429
|
if all:
|
|
406
430
|
for name, value in legacy.eager(self.model.items()):
|
|
407
|
-
if name in model:
|
|
431
|
+
if name in model:
|
|
432
|
+
continue
|
|
408
433
|
model[name] = value
|
|
409
434
|
|
|
410
435
|
# returns the model containing the "filtered" items resulting
|