nsj-rest-lib2 0.0.11__py3-none-any.whl → 0.0.12__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.
@@ -105,6 +105,7 @@ class EDLCompiler:
105
105
  enum_classes,
106
106
  related_imports,
107
107
  relations_dependencies,
108
+ fixed_filters,
108
109
  ) = self._properties_compiler.compile(
109
110
  properties_structure,
110
111
  map_unique_by_property,
@@ -114,7 +115,11 @@ class EDLCompiler:
114
115
 
115
116
  # Gerando o código do DTO
116
117
  dto_class_name, code_dto = self._dto_compiler.compile(
117
- entity_model, ast_dto_attributes, enum_classes, related_imports
118
+ entity_model,
119
+ ast_dto_attributes,
120
+ enum_classes,
121
+ related_imports,
122
+ fixed_filters,
118
123
  )
119
124
 
120
125
  # Gerando o código da Entity
@@ -3,6 +3,7 @@ import ast
3
3
  import black
4
4
 
5
5
  from nsj_rest_lib2.compiler.edl_model.entity_model import EntityModel
6
+ from nsj_rest_lib2.compiler.edl_model.primitives import BasicTypes
6
7
  from nsj_rest_lib2.compiler.util.str_util import CompilerStrUtil
7
8
  from nsj_rest_lib2.compiler.util.type_naming_util import compile_dto_class_name
8
9
 
@@ -17,6 +18,7 @@ class DTOCompiler:
17
18
  ast_dto_attributes: list[ast.stmt],
18
19
  enum_classes: list[ast.stmt],
19
20
  related_imports: list[tuple[str, str, str]],
21
+ fixed_filters: list[tuple[str, BasicTypes]],
20
22
  ) -> tuple[str, str]:
21
23
  """
22
24
  Compila o código do DTO a partir do AST e retorna o código compilado.
@@ -71,6 +73,18 @@ class DTOCompiler:
71
73
  names=[ast.alias(name="DTOBase", asname=None)],
72
74
  level=0,
73
75
  ),
76
+ # from nsj_rest_lib.descriptor.dto_left_join_field import EntityRelationOwner
77
+ ast.ImportFrom(
78
+ module="nsj_rest_lib.descriptor.dto_left_join_field",
79
+ names=[ast.alias(name="EntityRelationOwner", asname=None)],
80
+ level=0,
81
+ ),
82
+ # from nsj_rest_lib.descriptor.dto_object_field import DTOObjectField
83
+ ast.ImportFrom(
84
+ module="nsj_rest_lib.descriptor.dto_object_field",
85
+ names=[ast.alias(name="DTOObjectField", asname=None)],
86
+ level=0,
87
+ ),
74
88
  ]
75
89
 
76
90
  for import_ in related_imports:
@@ -89,6 +103,19 @@ class DTOCompiler:
89
103
  )
90
104
  )
91
105
 
106
+ # Keywords para tipos usados em fixed_filters
107
+ keywords_decorator_dto = []
108
+ for fixed_filter in fixed_filters:
109
+ keywords_decorator_dto.append(
110
+ ast.keyword(
111
+ arg="fixed_filters",
112
+ value=ast.Dict(
113
+ keys=[ast.Constant(value=fixed_filter[0])],
114
+ values=[ast.Constant(value=fixed_filter[1])],
115
+ ),
116
+ )
117
+ )
118
+
92
119
  # Criando o ast da classe
93
120
  class_name = compile_dto_class_name(entity_model.id)
94
121
  ast_class = ast.ClassDef(
@@ -99,7 +126,7 @@ class DTOCompiler:
99
126
  ast.Call(
100
127
  func=ast.Name(id="DTO", ctx=ast.Load()),
101
128
  args=[],
102
- keywords=[],
129
+ keywords=keywords_decorator_dto,
103
130
  )
104
131
  ],
105
132
  body=ast_dto_attributes,
@@ -1,5 +1,5 @@
1
1
  from pydantic import BaseModel, Field, model_validator
2
- from typing import List, Optional, Literal
2
+ from typing import Optional
3
3
 
4
4
 
5
5
  class ColumnMetaModel(BaseModel):
@@ -1,6 +1,8 @@
1
+ from typing import List, Optional
1
2
  from pydantic import BaseModel, Field
2
3
 
3
4
  from nsj_rest_lib2.compiler.edl_model.primitives import BasicTypes, PropertyType
5
+ from nsj_rest_lib2.compiler.edl_model.property_meta_model import DomainConfigModel
4
6
 
5
7
 
6
8
  class TraitPropertyMetaModel(BaseModel):
@@ -8,3 +10,7 @@ class TraitPropertyMetaModel(BaseModel):
8
10
  value: BasicTypes = Field(
9
11
  ..., description="Valor fixo da propriedade de condicionamento do trait."
10
12
  )
13
+ domain_config: Optional[List[DomainConfigModel]] = Field(
14
+ None,
15
+ description="Lista de valores permitidos.",
16
+ )
@@ -7,12 +7,16 @@ from nsj_rest_lib2.compiler.compiler_structures import (
7
7
  )
8
8
  from nsj_rest_lib2.compiler.edl_model.entity_model import EntityModel
9
9
  from nsj_rest_lib2.compiler.edl_model.primitives import (
10
+ BasicTypes,
10
11
  CardinalityTypes,
11
12
  PrimitiveTypes,
12
13
  REGEX_EXTERNAL_REF,
13
14
  REGEX_INTERNAL_REF,
14
15
  )
15
16
  from nsj_rest_lib2.compiler.edl_model.property_meta_model import PropertyMetaModel
17
+ from nsj_rest_lib2.compiler.edl_model.trait_property_meta_model import (
18
+ TraitPropertyMetaModel,
19
+ )
16
20
  from nsj_rest_lib2.compiler.model import RelationDependency
17
21
  from nsj_rest_lib2.compiler.util.str_util import CompilerStrUtil
18
22
  from nsj_rest_lib2.compiler.util.type_naming_util import (
@@ -42,6 +46,7 @@ class EDLPropertyCompiler:
42
46
  list[ast.stmt],
43
47
  list[tuple[str, str, str]],
44
48
  list[RelationDependency],
49
+ list[tuple[str, BasicTypes]],
45
50
  ]:
46
51
 
47
52
  # TODO Criar opção de campo calculado?
@@ -73,6 +78,7 @@ class EDLPropertyCompiler:
73
78
  enum_classes = []
74
79
  related_imports = []
75
80
  relations_dependencies = []
81
+ fixed_filters = []
76
82
 
77
83
  if properties_structure.properties is None:
78
84
  return (ast_dto_attributes, ast_entity_attributes, props_pk, enum_classes)
@@ -83,7 +89,7 @@ class EDLPropertyCompiler:
83
89
  # DTO
84
90
  ## Tratando propriedade simples (não array, não object)
85
91
  if isinstance(prop.type, PrimitiveTypes):
86
- self.compile_simple_property(
92
+ self._compile_simple_property(
87
93
  properties_structure,
88
94
  map_unique_by_property,
89
95
  entity_model,
@@ -97,127 +103,48 @@ class EDLPropertyCompiler:
97
103
 
98
104
  elif isinstance(prop.type, str):
99
105
  external_match = re.match(REGEX_EXTERNAL_REF, prop.type)
106
+ internal_match = re.match(REGEX_INTERNAL_REF, prop.type)
100
107
 
101
108
  if external_match:
102
109
  # Resolvendo o id da entidade
103
110
  related_entity_id = external_match.group(2)
104
-
105
- # Resolvendo o nome das classes de DTO e Entity
106
- related_dto_class_name = compile_dto_class_name(related_entity_id)
107
- related_entity_class_name = compile_entity_class_name(
108
- related_entity_id
109
- )
110
-
111
- # Resolvendo o caminho do import
112
111
  related_entity_key = external_match.group(0)
113
112
 
114
- related_entity = entity_models.get(related_entity_key)
115
- if not related_entity:
116
- raise Exception(
117
- f"Entidade '{entity_model.id}' possui uma referência externa para uma entidade inexistente: '{related_entity_key}', por meio da propriedade: '{pkey}'."
118
- )
119
-
120
- tenant = related_entity.tenant
121
- grupo_empresarial = related_entity.grupo_empresarial
122
- grupo_key, tenant_key, default_key = compile_namespace_keys(
123
- tenant, grupo_empresarial
113
+ self._compile_external_relation(
114
+ related_entity_id,
115
+ related_entity_key,
116
+ entity_model,
117
+ entity_models,
118
+ properties_structure,
119
+ ast_dto_attributes,
120
+ related_imports,
121
+ relations_dependencies,
122
+ pkey,
123
+ prop,
124
124
  )
125
125
 
126
- if (
127
- tenant
128
- and tenant != 0
129
- and grupo_empresarial
130
- and grupo_empresarial != "00000000-0000-0000-0000-000000000000"
131
- ):
132
- related_import = grupo_key
133
- elif tenant and tenant != 0:
134
- related_import = tenant_key
135
- else:
136
- related_import = default_key
137
-
138
- related_imports.append(
139
- (
140
- related_import,
141
- related_dto_class_name,
142
- related_entity_class_name,
143
- )
144
- )
145
-
146
- # Gravando a dependência de relacionamento
147
- relation_dependency = RelationDependency()
148
- relation_dependency.entity_resource = related_entity.api.resource
149
- relation_dependency.entity_scope = related_entity.escopo
150
- relation_dependency.tenant = tenant
151
- relation_dependency.grupo_empresarial = grupo_empresarial
152
- relations_dependencies.append(relation_dependency)
153
-
154
- # Instanciando o ast
155
- if prop.cardinality == CardinalityTypes.C1_N:
156
- # Para relacionamentos 1_N
157
- keywords = [
158
- ast.keyword(
159
- arg="dto_type",
160
- value=ast.Name(
161
- id=related_dto_class_name, ctx=ast.Load()
162
- ),
163
- ),
164
- ast.keyword(
165
- arg="entity_type",
166
- value=ast.Name(
167
- id=related_entity_class_name, ctx=ast.Load()
168
- ),
169
- ),
170
- ]
171
-
172
- # Resolvendo a coluna usada no relacionamento
173
- if (
174
- not properties_structure.entity_properties
175
- or pkey not in properties_structure.entity_properties
176
- or not properties_structure.entity_properties[
177
- pkey
178
- ].relation_column
179
- ):
180
- raise Exception(
181
- f"Propriedade '{pkey}' possui um relacionamento, mas nenhuma coluna de relacioanamento foi apontada na propriedade correspondente no repository."
182
- )
183
-
184
- relation_column = properties_structure.entity_properties[
185
- pkey
186
- ].relation_column
187
-
188
- keywords.append(
189
- ast.keyword(
190
- arg="related_entity_field",
191
- value=ast.Constant(value=relation_column),
192
- )
193
- )
194
-
195
- ast_attr = ast.AnnAssign(
196
- target=ast.Name(
197
- id=CompilerStrUtil.to_snake_case(pkey), ctx=ast.Store()
198
- ),
199
- annotation=ast.Name(
200
- id="list",
201
- ctx=ast.Load(),
202
- ),
203
- value=ast.Call(
204
- func=ast.Name(id="DTOListField", ctx=ast.Load()),
205
- args=[],
206
- keywords=keywords,
207
- ),
208
- simple=1,
209
- )
210
-
211
- ast_dto_attributes.append(ast_attr)
212
- else:
213
- # TODO
214
- pass
215
-
216
- elif re.match(REGEX_INTERNAL_REF, prop.type):
126
+ elif internal_match:
217
127
  # TODO
218
128
  pass
219
129
  else:
220
- raise Exception(f"Tipo de propriedade não suportado: {prop.type}")
130
+ raise Exception(
131
+ f"Tipo da propriedade '{pkey}' não suportado: {prop.type}"
132
+ )
133
+
134
+ for pkey in properties_structure.trait_properties:
135
+ prop = properties_structure.trait_properties[pkey]
136
+
137
+ self._compile_trait_property(
138
+ properties_structure,
139
+ map_unique_by_property,
140
+ pkey,
141
+ prop,
142
+ ast_dto_attributes,
143
+ ast_entity_attributes,
144
+ fixed_filters,
145
+ entity_model,
146
+ enum_classes,
147
+ )
221
148
 
222
149
  return (
223
150
  ast_dto_attributes,
@@ -226,9 +153,410 @@ class EDLPropertyCompiler:
226
153
  enum_classes,
227
154
  related_imports,
228
155
  relations_dependencies,
156
+ fixed_filters,
229
157
  )
230
158
 
231
- def compile_simple_property(
159
+ def _compile_trait_property(
160
+ self,
161
+ properties_structure: PropertiesCompilerStructure,
162
+ map_unique_by_property: dict[str, IndexCompilerStructure],
163
+ pkey: str,
164
+ prop: TraitPropertyMetaModel,
165
+ ast_dto_attributes: list[ast.stmt],
166
+ ast_entity_attributes: list[ast.stmt],
167
+ fixed_filters: list[tuple[str, BasicTypes]],
168
+ entity_model: EntityModel,
169
+ enum_classes: list[ast.stmt],
170
+ ):
171
+ enum_class_name = None
172
+ keywords = []
173
+
174
+ if (
175
+ properties_structure.main_properties
176
+ and pkey in properties_structure.main_properties
177
+ ):
178
+ keywords.append(ast.keyword(arg="resume", value=ast.Constant(True)))
179
+
180
+ if properties_structure.required and pkey in properties_structure.required:
181
+ keywords.append(ast.keyword(arg="not_null", value=ast.Constant(True)))
182
+
183
+ if (
184
+ properties_structure.partition_data
185
+ and pkey in properties_structure.partition_data
186
+ ):
187
+ keywords.append(ast.keyword(arg="partition_data", value=ast.Constant(True)))
188
+
189
+ if pkey in map_unique_by_property:
190
+ unique = map_unique_by_property[pkey].index_model
191
+ keywords.append(
192
+ ast.keyword(
193
+ arg="unique",
194
+ value=ast.Constant(unique.name),
195
+ )
196
+ )
197
+
198
+ if (
199
+ properties_structure.search_properties
200
+ and pkey in properties_structure.search_properties
201
+ ):
202
+ keywords.append(ast.keyword(arg="search", value=ast.Constant(True)))
203
+ else:
204
+ keywords.append(ast.keyword(arg="search", value=ast.Constant(False)))
205
+
206
+ if (
207
+ properties_structure.metric_label
208
+ and pkey in properties_structure.metric_label
209
+ ):
210
+ keywords.append(ast.keyword(arg="metric_label", value=ast.Constant(True)))
211
+
212
+ if prop.type == PrimitiveTypes.CPF:
213
+ keywords.append(
214
+ ast.keyword(
215
+ arg="validator",
216
+ value=ast.Attribute(
217
+ value=ast.Call(
218
+ func=ast.Name(id="DTOFieldValidators", ctx=ast.Load()),
219
+ args=[],
220
+ keywords=[],
221
+ ),
222
+ attr="validate_cpf",
223
+ ctx=ast.Load(),
224
+ ),
225
+ )
226
+ )
227
+ elif prop.type == PrimitiveTypes.CNPJ:
228
+ keywords.append(
229
+ ast.keyword(
230
+ arg="validator",
231
+ value=ast.Attribute(
232
+ value=ast.Call(
233
+ func=ast.Name(id="DTOFieldValidators", ctx=ast.Load()),
234
+ args=[],
235
+ keywords=[],
236
+ ),
237
+ attr="validate_cnpj",
238
+ ctx=ast.Load(),
239
+ ),
240
+ )
241
+ )
242
+ elif prop.type == PrimitiveTypes.CPF_CNPJ:
243
+ keywords.append(
244
+ ast.keyword(
245
+ arg="validator",
246
+ value=ast.Attribute(
247
+ value=ast.Call(
248
+ func=ast.Name(id="DTOFieldValidators", ctx=ast.Load()),
249
+ args=[],
250
+ keywords=[],
251
+ ),
252
+ attr="validate_cpf_or_cnpj",
253
+ ctx=ast.Load(),
254
+ ),
255
+ )
256
+ )
257
+ elif prop.type == PrimitiveTypes.EMAIL:
258
+ keywords.append(
259
+ ast.keyword(
260
+ arg="validator",
261
+ value=ast.Attribute(
262
+ value=ast.Call(
263
+ func=ast.Name(id="DTOFieldValidators", ctx=ast.Load()),
264
+ args=[],
265
+ keywords=[],
266
+ ),
267
+ attr="validate_email",
268
+ ctx=ast.Load(),
269
+ ),
270
+ )
271
+ )
272
+
273
+ # Trtando de uma definição de enum
274
+ if prop.domain_config:
275
+ result = self._compile_domain_config(pkey, prop, entity_model)
276
+ if not result:
277
+ raise Exception(f"Erro desconhecido ao compilar a propriedade {pkey}")
278
+
279
+ enum_class_name, ast_enum_class = result
280
+ enum_classes.append(ast_enum_class)
281
+
282
+ # Resolvendo o nome da propriedade no Entity
283
+ if (
284
+ properties_structure.entity_properties
285
+ and pkey in properties_structure.entity_properties
286
+ ):
287
+ entity_field_name = properties_structure.entity_properties[pkey].column
288
+ else:
289
+ entity_field_name = pkey
290
+
291
+ # Escrevendo, se necessário, o alias para o nome da entity
292
+ if entity_field_name != pkey:
293
+ keywords.append(
294
+ ast.keyword(
295
+ arg="entity_field",
296
+ value=ast.Constant(value=entity_field_name),
297
+ )
298
+ )
299
+
300
+ # Instanciando o atributo AST
301
+ if not isinstance(prop.type, PrimitiveTypes):
302
+ raise Exception(
303
+ f"Tipo da trait_property '{pkey}' não suportado: {prop.type} (deveria ser um Tipo Primitivo)"
304
+ )
305
+
306
+ # Instanciando o atributo AST
307
+ if enum_class_name:
308
+ prop_type = enum_class_name
309
+ else:
310
+ prop_type = TypeUtil.property_type_to_python_type(prop.type)
311
+
312
+ ast_attr = ast.AnnAssign(
313
+ target=ast.Name(id=CompilerStrUtil.to_snake_case(pkey), ctx=ast.Store()),
314
+ annotation=ast.Name(
315
+ id=prop_type,
316
+ ctx=ast.Load(),
317
+ ),
318
+ value=ast.Call(
319
+ func=ast.Name(id="DTOField", ctx=ast.Load()),
320
+ args=[],
321
+ keywords=keywords,
322
+ ),
323
+ simple=1,
324
+ )
325
+
326
+ ast_dto_attributes.append(ast_attr)
327
+
328
+ # Entity
329
+ ast_entity_attr = ast.AnnAssign(
330
+ target=ast.Name(
331
+ id=CompilerStrUtil.to_snake_case(entity_field_name),
332
+ ctx=ast.Store(),
333
+ ),
334
+ annotation=ast.Name(
335
+ id=TypeUtil.property_type_to_python_type(prop.type),
336
+ ctx=ast.Load(),
337
+ ),
338
+ value=ast.Constant(value=None),
339
+ simple=1,
340
+ )
341
+
342
+ ast_entity_attributes.append(ast_entity_attr)
343
+
344
+ # Guardando como um fixed_filter
345
+ # TODO Pernsar em validações para esse value (se está de acordo com o tipo ou enum)
346
+ fixed_filters.append((pkey, prop.value))
347
+
348
+ def _compile_external_relation(
349
+ self,
350
+ related_entity_id: str,
351
+ related_entity_key: str,
352
+ entity_model: EntityModel,
353
+ entity_models: dict[str, EntityModel],
354
+ properties_structure: PropertiesCompilerStructure,
355
+ ast_dto_attributes: list[ast.stmt],
356
+ related_imports: list[tuple[str, str, str]],
357
+ relations_dependencies: list[RelationDependency],
358
+ pkey: str,
359
+ prop: PropertyMetaModel,
360
+ ):
361
+ # Resolvendo o nome das classes de DTO e Entity
362
+ related_dto_class_name = compile_dto_class_name(related_entity_id)
363
+ related_entity_class_name = compile_entity_class_name(related_entity_id)
364
+
365
+ # Resolvendo o caminho do import
366
+ related_entity = entity_models.get(related_entity_key)
367
+ if not related_entity:
368
+ raise Exception(
369
+ f"Entidade '{entity_model.id}' possui uma referência externa para uma entidade inexistente: '{related_entity_key}', por meio da propriedade: '{pkey}'."
370
+ )
371
+
372
+ tenant = related_entity.tenant
373
+ grupo_empresarial = related_entity.grupo_empresarial
374
+ grupo_key, tenant_key, default_key = compile_namespace_keys(
375
+ tenant, grupo_empresarial
376
+ )
377
+
378
+ if (
379
+ tenant
380
+ and tenant != 0
381
+ and grupo_empresarial
382
+ and grupo_empresarial != "00000000-0000-0000-0000-000000000000"
383
+ ):
384
+ related_import = grupo_key
385
+ elif tenant and tenant != 0:
386
+ related_import = tenant_key
387
+ else:
388
+ related_import = default_key
389
+
390
+ related_imports.append(
391
+ (
392
+ related_import,
393
+ related_dto_class_name,
394
+ related_entity_class_name,
395
+ )
396
+ )
397
+
398
+ # Gravando a dependência de relacionamento
399
+ relation_dependency = RelationDependency()
400
+ relation_dependency.entity_resource = related_entity.api.resource
401
+ relation_dependency.entity_scope = related_entity.escopo
402
+ relation_dependency.tenant = tenant
403
+ relation_dependency.grupo_empresarial = grupo_empresarial
404
+ relations_dependencies.append(relation_dependency)
405
+
406
+ # Instanciando o ast
407
+ if prop.cardinality == CardinalityTypes.C1_N:
408
+ # Para relacionamentos 1_N
409
+ self._build_ast_1_N(
410
+ properties_structure,
411
+ ast_dto_attributes,
412
+ pkey,
413
+ related_dto_class_name,
414
+ related_entity_class_name,
415
+ )
416
+
417
+ elif prop.cardinality == CardinalityTypes.C1_1:
418
+ self._build_ast_1_1(
419
+ properties_structure,
420
+ ast_dto_attributes,
421
+ pkey,
422
+ related_dto_class_name,
423
+ related_entity_class_name,
424
+ )
425
+
426
+ elif prop.cardinality == CardinalityTypes.CN_N:
427
+ # TODO
428
+ pass
429
+ else:
430
+ raise Exception(
431
+ f"Propriedade '{pkey}' da entidade '{entity_model.id}' possui cardinalidade inválida ou não suportada: {prop.cardinality}"
432
+ )
433
+
434
+ def _build_ast_1_N(
435
+ self,
436
+ properties_structure: PropertiesCompilerStructure,
437
+ ast_dto_attributes: list[ast.stmt],
438
+ pkey: str,
439
+ related_dto_class_name: str,
440
+ related_entity_class_name: str,
441
+ ):
442
+ # Propriedade do property descriptor
443
+ keywords = [
444
+ ast.keyword(
445
+ arg="dto_type",
446
+ value=ast.Name(id=related_dto_class_name, ctx=ast.Load()),
447
+ ),
448
+ ast.keyword(
449
+ arg="entity_type",
450
+ value=ast.Name(id=related_entity_class_name, ctx=ast.Load()),
451
+ ),
452
+ ]
453
+
454
+ # Resolvendo a coluna usada no relacionamento
455
+ if (
456
+ not properties_structure.entity_properties
457
+ or pkey not in properties_structure.entity_properties
458
+ or not properties_structure.entity_properties[pkey].relation_column
459
+ ):
460
+ raise Exception(
461
+ f"Propriedade '{pkey}' possui um relacionamento, mas nenhuma coluna de relacioanamento foi apontada na propriedade correspondente no repository."
462
+ )
463
+
464
+ relation_column = properties_structure.entity_properties[pkey].relation_column
465
+
466
+ keywords.append(
467
+ ast.keyword(
468
+ arg="related_entity_field",
469
+ value=ast.Constant(value=relation_column),
470
+ )
471
+ )
472
+
473
+ ast_attr = ast.AnnAssign(
474
+ target=ast.Name(id=CompilerStrUtil.to_snake_case(pkey), ctx=ast.Store()),
475
+ annotation=ast.Name(
476
+ id="list",
477
+ ctx=ast.Load(),
478
+ ),
479
+ value=ast.Call(
480
+ func=ast.Name(id="DTOListField", ctx=ast.Load()),
481
+ args=[],
482
+ keywords=keywords,
483
+ ),
484
+ simple=1,
485
+ )
486
+
487
+ ast_dto_attributes.append(ast_attr)
488
+
489
+ def _build_ast_1_1(
490
+ self,
491
+ properties_structure: PropertiesCompilerStructure,
492
+ ast_dto_attributes: list[ast.stmt],
493
+ pkey: str,
494
+ related_dto_class_name: str,
495
+ related_entity_class_name: str,
496
+ ):
497
+ # Propriedade do property descriptor
498
+ keywords = [
499
+ ast.keyword(
500
+ arg="entity_type",
501
+ value=ast.Name(id=related_entity_class_name, ctx=ast.Load()),
502
+ ),
503
+ ]
504
+
505
+ # Resolvendo a coluna usada no relacionamento
506
+ if (
507
+ not properties_structure.entity_properties
508
+ or pkey not in properties_structure.entity_properties
509
+ or not properties_structure.entity_properties[pkey].relation_column
510
+ ):
511
+ raise Exception(
512
+ f"Propriedade '{pkey}' possui um relacionamento, mas nenhuma coluna de relacioanamento foi apontada na propriedade correspondente no repository."
513
+ )
514
+
515
+ relation_column = str(
516
+ properties_structure.entity_properties[pkey].relation_column
517
+ )
518
+
519
+ owner_relation = False
520
+ if "/" in relation_column:
521
+ owner_relation = True
522
+ relation_column = relation_column.split("/")[-1]
523
+
524
+ keywords.append(
525
+ ast.keyword(
526
+ arg="relation_field",
527
+ value=ast.Constant(value=relation_column),
528
+ )
529
+ )
530
+
531
+ if not owner_relation:
532
+ keywords.append(
533
+ ast.keyword(
534
+ arg="entity_relation_owner",
535
+ value=ast.Attribute(
536
+ value=ast.Name(id="EntityRelationOwner", ctx=ast.Load()),
537
+ attr="OTHER",
538
+ ctx=ast.Load(),
539
+ ),
540
+ )
541
+ )
542
+
543
+ ast_attr = ast.AnnAssign(
544
+ target=ast.Name(id=CompilerStrUtil.to_snake_case(pkey), ctx=ast.Store()),
545
+ annotation=ast.Name(
546
+ id=related_dto_class_name,
547
+ ctx=ast.Load(),
548
+ ),
549
+ value=ast.Call(
550
+ func=ast.Name(id="DTOObjectField", ctx=ast.Load()),
551
+ args=[],
552
+ keywords=keywords,
553
+ ),
554
+ simple=1,
555
+ )
556
+
557
+ ast_dto_attributes.append(ast_attr)
558
+
559
+ def _compile_simple_property(
232
560
  self,
233
561
  properties_structure,
234
562
  map_unique_by_property,
@@ -473,7 +801,7 @@ class EDLPropertyCompiler:
473
801
  def _compile_domain_config(
474
802
  self,
475
803
  pkey: str,
476
- prop: PropertyMetaModel,
804
+ prop: PropertyMetaModel | TraitPropertyMetaModel,
477
805
  entity_model: EntityModel,
478
806
  ) -> tuple[str, ast.stmt] | None:
479
807
  if not prop.domain_config:
@@ -47,7 +47,7 @@ class EntityLoader:
47
47
  entity_resource: str,
48
48
  tenant: str | None,
49
49
  grupo_empresarial: str | None,
50
- scope: str = ESCOPO_RESTLIB2,
50
+ escopo: str = ESCOPO_RESTLIB2,
51
51
  ) -> tuple[str, str, dict, bool, list[str]]:
52
52
  # Montando as chaves dos namespaces
53
53
  grupo_key, tenant_key, default_key = compile_namespace_keys(
@@ -103,6 +103,7 @@ class EntityLoader:
103
103
  tenant_key,
104
104
  default_key,
105
105
  entity_config_key,
106
+ escopo=escopo,
106
107
  )
107
108
 
108
109
  # Se não achar no redis, usa o que estava em memória
@@ -162,7 +163,12 @@ class EntityLoader:
162
163
 
163
164
  # Se não conseguir recuperar a entidade, procura no redis:
164
165
  loaded_config = self._load_entity_config_from_redis(
165
- entity_resource, grupo_key, tenant_key, default_key, None
166
+ entity_resource,
167
+ grupo_key,
168
+ tenant_key,
169
+ default_key,
170
+ None,
171
+ escopo=escopo,
166
172
  )
167
173
 
168
174
  # Se também não achar no redis, lanca exceção
@@ -341,30 +347,31 @@ class EntityLoader:
341
347
  tenant_key: str,
342
348
  default_key: str,
343
349
  entity_config_key: str | None,
350
+ escopo: str,
344
351
  ) -> tuple[str, str] | None:
345
352
  get_logger().debug(
346
- f"Procurando a configuração da entidade {entity_resource} no redis"
353
+ f"Procurando a configuração da entidade {entity_resource} no redis. Tenant key: {tenant_key} e Grupo key: {grupo_key}"
347
354
  )
348
355
 
349
356
  if entity_config_key is not None:
350
357
  entity_config_str = get_redis(
351
- "entity_config", ESCOPO_RESTLIB2, entity_config_key, entity_resource
358
+ "entity_config", escopo, entity_config_key, entity_resource
352
359
  )
353
360
 
354
361
  else:
355
362
  entity_config_key = grupo_key
356
363
  entity_config_str = get_redis(
357
- "entity_config", ESCOPO_RESTLIB2, grupo_key, entity_resource
364
+ "entity_config", escopo, grupo_key, entity_resource
358
365
  )
359
366
  if entity_config_str is None:
360
367
  entity_config_key = tenant_key
361
368
  entity_config_str = get_redis(
362
- "entity_config", ESCOPO_RESTLIB2, tenant_key, entity_resource
369
+ "entity_config", escopo, tenant_key, entity_resource
363
370
  )
364
371
  if entity_config_str is None:
365
372
  entity_config_key = default_key
366
373
  entity_config_str = get_redis(
367
- "entity_config", ESCOPO_RESTLIB2, default_key, entity_resource
374
+ "entity_config", escopo, default_key, entity_resource
368
375
  )
369
376
 
370
377
  # Se não encontrar no redis, retorna None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nsj_rest_lib2
3
- Version: 0.0.11
3
+ Version: 0.0.12
4
4
  Summary: Biblioteca para permitir a distribuição de rotas dinâmicas numa API, configuradas por meio de EDLs declarativos (em formato JSON).
5
5
  Home-page: https://github.com/Nasajon/nsj_rest_lib2
6
6
  Author: Nasajon Sistemas
@@ -4,22 +4,22 @@ nsj_rest_lib2/redis_config.py,sha256=4KLcvYS3nJO7PMQgF6F9_j6r-TyqcS7TBbd3LEQuKDU
4
4
  nsj_rest_lib2/settings.py,sha256=Hn_o1HZmievnYb8D1kNT2Nq-OEjxbyNjOiOpbnFsMwE,367
5
5
  nsj_rest_lib2/compiler/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  nsj_rest_lib2/compiler/ai_compiler.py,sha256=shAtN4T0ai_52qh15L3mK1QbeC6glHOR6C3J3gj14II,9029
7
- nsj_rest_lib2/compiler/compiler.py,sha256=bn780zjNHaopmhOzi0olMhwdh89uFJUKiCDRQActKGI,12243
7
+ nsj_rest_lib2/compiler/compiler.py,sha256=tWnhDuHpvpJMWMPxt6U76ZS6J-hSpiB7xRZaeOP3CMc,12334
8
8
  nsj_rest_lib2/compiler/compiler_structures.py,sha256=2bM4_7lG1fytDGxJl6SU9pLsbspiNV36gVn9-O-23Q8,1009
9
- nsj_rest_lib2/compiler/dto_compiler.py,sha256=GAKWFvks0Duqs2EsEr1-BFx2-Kny72jJMbl9ZyIEDXw,4125
9
+ nsj_rest_lib2/compiler/dto_compiler.py,sha256=4e9_8EsNSHPCUEmiuEPdudj9_tFuw2O4ZTv6EYwJrGc,5333
10
10
  nsj_rest_lib2/compiler/entity_compiler.py,sha256=zLXO6USY4Rr0Hnk4wGep5K8DiHxJv-W-BBz_-g4OhCA,4307
11
11
  nsj_rest_lib2/compiler/model.py,sha256=QDBoM26qoZdiNcykl1nvXCrFDhg-6Q__QzVq6uY1QzE,1460
12
- nsj_rest_lib2/compiler/property_compiler.py,sha256=xVwql97vPdxln0z3zdigruYIujCA6978LfxGsLi6QhY,19527
12
+ nsj_rest_lib2/compiler/property_compiler.py,sha256=kr9Pi0kkIrvgEmxrmV_NEQuqekM1h6-jqvF85nZTUcY,29808
13
13
  nsj_rest_lib2/compiler/edl_model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  nsj_rest_lib2/compiler/edl_model/ai_entity_edl.py,sha256=664QBDcOgVnyfwtUOXO1W7AKaZhueBG335x5DuogruY,7644
15
15
  nsj_rest_lib2/compiler/edl_model/api_model.py,sha256=pH0Uiq_64AGvkHqwY44TrulWWZXbi6M0EKJWUhSqKj0,837
16
- nsj_rest_lib2/compiler/edl_model/column_meta_model.py,sha256=3OLsRwEz66Cktzew6Hie3HZXK9u20GXlWUU0HtFtwfk,709
16
+ nsj_rest_lib2/compiler/edl_model/column_meta_model.py,sha256=s0sEVkoW1hV2_hto1mws4XhzKGH_b4NzhaOiwFH25Ks,694
17
17
  nsj_rest_lib2/compiler/edl_model/entity_model.py,sha256=sXVfC30P3-q2-fQ3XB_-3vpNjqFPIK5oBIVbwkXNFLU,3662
18
18
  nsj_rest_lib2/compiler/edl_model/index_model.py,sha256=cXWlu0hxtro5vvYoirkDW4R3PCnBW5oCCWjRJ6AX5zE,508
19
19
  nsj_rest_lib2/compiler/edl_model/primitives.py,sha256=cWEys87xDpgotyRUXkzvFvY4LHeawzBEEyz0Xed18AQ,1454
20
20
  nsj_rest_lib2/compiler/edl_model/property_meta_model.py,sha256=x2SApvI-5MZTErAHeOXnR6qfjflhSs8r6Y9KMtCykV0,3960
21
21
  nsj_rest_lib2/compiler/edl_model/repository_model.py,sha256=Vt1HxlaoifP4w5ij1laKDkD1-COBihE8EX1HkdEDUSo,977
22
- nsj_rest_lib2/compiler/edl_model/trait_property_meta_model.py,sha256=ZC2oTvc9Y2Oiy4NLNHQLiMOLRWDAOdF8GJxOw4nqHdk,354
22
+ nsj_rest_lib2/compiler/edl_model/trait_property_meta_model.py,sha256=SBSfiu4v0PMsWRsGDySR3P2tkabLbDZxx_FFy_3rGXA,605
23
23
  nsj_rest_lib2/compiler/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
24
24
  nsj_rest_lib2/compiler/util/str_util.py,sha256=lVP1yHhj1pOd6ULtTnkcfX6Gqrpe4yCBratHUhBNGcI,843
25
25
  nsj_rest_lib2/compiler/util/type_naming_util.py,sha256=sahlxtYUPcksqlX1hygaoTF7vuD8tY8eosgOR04YLAs,612
@@ -27,8 +27,8 @@ nsj_rest_lib2/compiler/util/type_util.py,sha256=HTKOH4uRTOY0YgoM8oUv_6cEcReE_bgK
27
27
  nsj_rest_lib2/controller/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
28
28
  nsj_rest_lib2/controller/dynamic_controller.py,sha256=XMqxe1NW-NE5XwomXb4pSNdALQHpP74Hc26R4fnmXqg,15194
29
29
  nsj_rest_lib2/service/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
- nsj_rest_lib2/service/entity_loader.py,sha256=es8qWyI0UNGf1wdEFnAmTYo8eW-XMIi7Ar_SgTfjQNQ,15224
31
- nsj_rest_lib2-0.0.11.dist-info/METADATA,sha256=xQRuH1m7gLxd3oW6Mh_e5iWRTSs660KlkSP7bes91FM,1361
32
- nsj_rest_lib2-0.0.11.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
33
- nsj_rest_lib2-0.0.11.dist-info/top_level.txt,sha256=L6zh0EfH8_rur7OJ8_V-El-XEMf4qg3bkF8ADgqLVIA,14
34
- nsj_rest_lib2-0.0.11.dist-info/RECORD,,
30
+ nsj_rest_lib2/service/entity_loader.py,sha256=KVLFQSqj4DL-K-T29ksJE2or9QkekFmyAGUIKjQX6Qk,15372
31
+ nsj_rest_lib2-0.0.12.dist-info/METADATA,sha256=CTk1vS9FJ_U2e6-Vz38wj3Ba2efwuKPW-iDpHlosHzk,1361
32
+ nsj_rest_lib2-0.0.12.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
33
+ nsj_rest_lib2-0.0.12.dist-info/top_level.txt,sha256=L6zh0EfH8_rur7OJ8_V-El-XEMf4qg3bkF8ADgqLVIA,14
34
+ nsj_rest_lib2-0.0.12.dist-info/RECORD,,