edu-rdm-integration 0.4.4__py3-none-any.whl → 0.4.6__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.
@@ -2,12 +2,16 @@ from typing import (
2
2
  Any,
3
3
  Dict,
4
4
  Optional,
5
+ NamedTuple,
5
6
  )
6
7
 
7
8
  from edu_rdm_integration.adapters.caches import (
8
9
  WebEduEntityCache,
9
10
  )
10
11
 
12
+ from educommon.integration_entities.enums import (
13
+ EntityLogOperation,
14
+ )
11
15
 
12
16
  class WebEduEntityCacheExtended(WebEduEntityCache):
13
17
  """
@@ -43,3 +47,25 @@ class WebEduEntityCacheExtended(WebEduEntityCache):
43
47
  self._entities = self._entities.only(*self._only_fields)
44
48
 
45
49
  self._entities = self._entities.distinct()
50
+
51
+
52
+ class LogChange(NamedTuple):
53
+ """Операция и значения измененных полей из лога."""
54
+
55
+ operation: EntityLogOperation
56
+ fields: Dict[str, Any]
57
+
58
+ @property
59
+ def is_create(self) -> bool:
60
+ """Лог создания."""
61
+ return self.operation == EntityLogOperation.CREATE
62
+
63
+ @property
64
+ def is_update(self) -> bool:
65
+ """Лог изменения."""
66
+ return self.operation == EntityLogOperation.UPDATE
67
+
68
+ @property
69
+ def is_delete(self) -> bool:
70
+ """Лог удаления."""
71
+ return self.operation == EntityLogOperation.DELETE
@@ -0,0 +1,78 @@
1
+ from edu_rdm_integration.collect_data.base.caches import (
2
+ LogChange,
3
+ )
4
+ from edu_rdm_integration.mapping import (
5
+ MODEL_FIELDS_LOG_FILTER,
6
+ )
7
+
8
+ from educommon.audit_log.utils import (
9
+ get_model_by_table,
10
+ )
11
+ from educommon.integration_entities.consts import (
12
+ LOG_OPERATION_MAP,
13
+ )
14
+ from educommon.integration_entities.enums import (
15
+ EntityLogOperation,
16
+ )
17
+
18
+
19
+ class ReformatLogsMixin:
20
+ """Миксин для преобразования логов к удобному для работы виду в кешах помощников функций."""
21
+
22
+ def _reformat_logs(self):
23
+ """
24
+ Производится преобразование логов к удобному для работы виду.
25
+
26
+ Предполагается вложенные словари. На первом уровне ключом будет название
27
+ модели, на втором идентификатор записи.
28
+ """
29
+ for log in self.raw_logs:
30
+ model = get_model_by_table(log.table)._meta.label
31
+
32
+ if getattr(self, '_log_only_models', None) and (model not in self._log_only_models):
33
+ # Пропускаем, если модель не входит в список отслеживаемых
34
+ continue
35
+
36
+ operation = LOG_OPERATION_MAP[log.operation]
37
+
38
+ if operation in EntityLogOperation.values:
39
+ fields = log.data
40
+ else:
41
+ fields = {}
42
+
43
+ log_change = LogChange(
44
+ operation=operation,
45
+ fields=fields,
46
+ )
47
+
48
+ if not self._filter_log(model, log_change):
49
+ # Если модель не отслеживается, то запись лога не сохраняем
50
+ continue
51
+
52
+ if log_change.operation == EntityLogOperation.DELETE:
53
+ self.logs[model][log.object_id] = [log_change, ]
54
+ else:
55
+ self.logs[model][log.object_id].append(log_change)
56
+
57
+ @staticmethod
58
+ def _filter_log(model: str, log_change: LogChange) -> bool:
59
+ """
60
+ Производится проверка изменений на отслеживаемые поля.
61
+ """
62
+ is_filtered = False
63
+
64
+ if model in MODEL_FIELDS_LOG_FILTER[log_change.operation]:
65
+ filter_fields = MODEL_FIELDS_LOG_FILTER[log_change.operation][model]
66
+ if filter_fields:
67
+ # Если заданы конкретные поля, которые должны отслеживать
68
+ for field in log_change.fields:
69
+ if field in filter_fields:
70
+ # Достаточно, чтобы хотя бы одно поле попало под фильтр
71
+ is_filtered = True
72
+ break
73
+ else:
74
+ # Модель отслеживается, но перечень фильтруемых полей не задан,
75
+ # значит фильтруем все поля модели
76
+ is_filtered = True
77
+
78
+ return is_filtered
@@ -28,6 +28,13 @@ from edu_rdm_integration.adapters.caches import (
28
28
  from edu_rdm_integration.collect_data.calculated.base.consts import (
29
29
  LOOKUP_SEP,
30
30
  )
31
+ from educommon.utils.conversion import (
32
+ int_or_none,
33
+ )
34
+
35
+ from edu_rdm_integration.collect_data.base.mixins import (
36
+ ReformatLogsMixin,
37
+ )
31
38
 
32
39
 
33
40
  class BaseCollectingCalculatedExportedDataRunnerCacheStorage(WebEduRunnerCacheStorage):
@@ -36,7 +43,7 @@ class BaseCollectingCalculatedExportedDataRunnerCacheStorage(WebEduRunnerCacheSt
36
43
  """
37
44
 
38
45
 
39
- class BaseCollectingCalculatedExportedDataFunctionCacheStorage(WebEduFunctionCacheStorage):
46
+ class BaseCollectingCalculatedExportedDataFunctionCacheStorage(ReformatLogsMixin, WebEduFunctionCacheStorage):
40
47
  """
41
48
  Базовый кеш помощников функций сбора расчетных данных для интеграции с "Региональная витрина данных".
42
49
  """
@@ -60,14 +67,6 @@ class BaseCollectingCalculatedExportedDataFunctionCacheStorage(WebEduFunctionCac
60
67
  # }
61
68
  self.logs = defaultdict(lambda: defaultdict(list))
62
69
 
63
- def _reformat_logs(self):
64
- """
65
- Производится преобразование логов к удобному для работы виду.
66
-
67
- Предполагается вложенные словари. На первом уровне ключом будет название
68
- модели, на втором идентификатор записи.
69
- """
70
-
71
70
  def _prepare_logs(self):
72
71
  """
73
72
  Подготовка логов для дальнейшей работы.
@@ -67,7 +67,7 @@ class BaseCollectingExportedDataFunctionCacheStorage(WebEduFunctionCacheStorage)
67
67
  Базовый кеш помощников функций сбора данных для интеграции с "Региональная витрина данных".
68
68
  """
69
69
 
70
- def __init__(self, raw_logs, *args, **kwargs):
70
+ def __init__(self, raw_logs, is_merge_logs=False, *args, **kwargs):
71
71
  super().__init__(*args, **kwargs)
72
72
 
73
73
  # Необработанные логи как есть.
@@ -75,7 +75,7 @@ class BaseCollectingExportedDataFunctionCacheStorage(WebEduFunctionCacheStorage)
75
75
 
76
76
  # TODO Перенести в базовый класс (https://jira.bars.group/browse/EDUSCHL-19991)
77
77
  # Необходимость объединения логов относящихся к одному объекту
78
- self.is_merge_logs = True
78
+ self.is_merge_logs = is_merge_logs
79
79
 
80
80
  # Подготовленные логи в виде:
81
81
  # {
@@ -149,7 +149,20 @@ class BaseCollectingExportedDataFunctionCacheStorage(WebEduFunctionCacheStorage)
149
149
  if log_change.operation == EntityLogOperation.DELETE:
150
150
  self.logs[model][log.object_id] = [log_change, ]
151
151
  else:
152
- self.logs[model][log.object_id].append(log_change)
152
+ if self.is_merge_logs:
153
+ self._merge_logs(self.logs[model][log.object_id], log_change)
154
+ else:
155
+ self.logs[model][log.object_id].append(log_change)
156
+
157
+ @staticmethod
158
+ def _merge_logs(log_changes: List[LogChange], log_change: LogChange):
159
+ """
160
+ Производит объединение (накопление) изменений полей в рамках одного объекта.
161
+ """
162
+ if log_changes:
163
+ log_changes[0].fields.update(log_change.fields)
164
+ else:
165
+ log_changes.append(log_change)
153
166
 
154
167
  def _prepare_logs(self):
155
168
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: edu-rdm-integration
3
- Version: 0.4.4
3
+ Version: 0.4.6
4
4
  Summary: Интеграция с Региональной витриной данных
5
5
  Home-page:
6
6
  Download-URL:
@@ -215,6 +215,30 @@ ENABLE_REQUEST_EMULATION = True
215
215
 
216
216
  ### Исправлено
217
217
 
218
+ ## [0.4.6] - 2023-08-16
219
+
220
+ Удален лишний вызов метода _prepare_logs
221
+
222
+ ### Добавлено
223
+
224
+ ### Изменено
225
+
226
+ ### Исправлено
227
+ - [EDUSCHL-19991](https://jira.bars.group/browse/EDUSCHL-19991)
228
+ PATCH удален лишний вызов метода ```_prepare_logs``` в методе ```__init__``` класса ```BaseCollectingCalculatedExportedDataFunctionCacheStorage```
229
+
230
+ ## [0.4.5] - 2023-08-09
231
+
232
+ Объединение обрабатываемых логов относящихся к одному объекту
233
+
234
+ ### Добавлено
235
+
236
+ - [EDUSCHL-19991](https://jira.bars.group/browse/EDUSCHL-19991)
237
+ PATCH Новый миксин ```ReformatLogsMixin``` , новое поле is_merge_logs и новый метод _merge_logs у класса ```BaseCollectingExportedDataFunctionCacheStorage```
238
+
239
+ ### Изменено
240
+
241
+ ### Исправлено
218
242
 
219
243
  ## [0.4.4] - 2023-08-12
220
244
 
@@ -30,14 +30,15 @@ edu_rdm_integration/collect_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRk
30
30
  edu_rdm_integration/collect_data/collect.py,sha256=4aeIb44l6u-RYcIDGU1c840GZ0nNFAb6l5e0gGdFuhQ,14739
31
31
  edu_rdm_integration/collect_data/generators.py,sha256=GJpOWDp1jeQQPI4Zx4w0BxaAaGu6S3ow63UMEfvcFl0,8974
32
32
  edu_rdm_integration/collect_data/base/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
- edu_rdm_integration/collect_data/base/caches.py,sha256=xpiSabHHS4NRqwZOeOk_7Zh8vHOyEmY1DmBwgFsBvx8,1310
33
+ edu_rdm_integration/collect_data/base/caches.py,sha256=vOfYoWfFdYbhnOwmeEdOB_ErieQrMlORXqojVCiGKrA,2029
34
34
  edu_rdm_integration/collect_data/base/functions.py,sha256=0vAOx4lrEbBOxFbeCl_wB7imfYq1EgqwTvmqUbrXgT4,2403
35
35
  edu_rdm_integration/collect_data/base/managers.py,sha256=UkiFhyD3Gn3drErXc0NjQkSyPan10BkQp-yx-2vc_AM,6067
36
+ edu_rdm_integration/collect_data/base/mixins.py,sha256=vgWCsSgjtUjvu-fMBByEq6xbIocjzjmdNzhMs5DRKVI,3180
36
37
  edu_rdm_integration/collect_data/base/runners.py,sha256=mqrdVUMud7ss-0Iufj3DHEdy7BDHgbkZ7ZEGJfUaslc,2835
37
38
  edu_rdm_integration/collect_data/calculated/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
39
  edu_rdm_integration/collect_data/calculated/strategies.py,sha256=S-a6DA8E0CTMOxLg9Xk_7c3ZbN-ngmaNnKycoJnCLTs,7621
39
40
  edu_rdm_integration/collect_data/calculated/base/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
40
- edu_rdm_integration/collect_data/calculated/base/caches.py,sha256=9Xx7DwS_bN3SoGDDhrh6ONGi1vo08wmYcUMA9Q0C1KA,7774
41
+ edu_rdm_integration/collect_data/calculated/base/caches.py,sha256=_yOaT0dylONACvA0ca5RZ0IQu7t9YW_S69y0KqDbVCA,7534
41
42
  edu_rdm_integration/collect_data/calculated/base/consts.py,sha256=DsgPOF_2iCzZTPity27oDDkpS6Axdhd5C94uSkIwA1g,84
42
43
  edu_rdm_integration/collect_data/calculated/base/enums.py,sha256=BSmwrkzYwEQhz9NbZCJsldY532PqgZJzxzsVk6ue0bM,93
43
44
  edu_rdm_integration/collect_data/calculated/base/errors.py,sha256=bDVjmB43pZJ2C8sNnqF177qMB4l_XskDpVTFqTmxjj8,326
@@ -53,7 +54,7 @@ edu_rdm_integration/collect_data/calculated/base/validators.py,sha256=xIaSIE9oKb
53
54
  edu_rdm_integration/collect_data/non_calculated/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
54
55
  edu_rdm_integration/collect_data/non_calculated/strategies.py,sha256=5mC1g1ynjvGX2wRBJ2MPHo8DfaxbEiBd4H_k65IQvT8,7423
55
56
  edu_rdm_integration/collect_data/non_calculated/base/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
56
- edu_rdm_integration/collect_data/non_calculated/base/caches.py,sha256=MMkfQuAs0jZFOMKjE-DojlFt4PTCdEgKIt_KMXPJxYs,6236
57
+ edu_rdm_integration/collect_data/non_calculated/base/caches.py,sha256=qRC92vy-oUcyokAF279CcZgWTl_x-PxsGAK-5Rb31-g,6821
57
58
  edu_rdm_integration/collect_data/non_calculated/base/consts.py,sha256=pds1t4eHzovm7Yz2o5je3UHqRE8gqfT2sL-IwpoBN_o,66
58
59
  edu_rdm_integration/collect_data/non_calculated/base/enums.py,sha256=BSmwrkzYwEQhz9NbZCJsldY532PqgZJzxzsVk6ue0bM,93
59
60
  edu_rdm_integration/collect_data/non_calculated/base/errors.py,sha256=dGawEQ2ItTxlFt9ynhYhpqx40Qmrlg2rOskH0DsNVnQ,297
@@ -94,9 +95,9 @@ edu_rdm_integration/management/commands/export_entities_data.py,sha256=Mas1zwsH-
94
95
  edu_rdm_integration/migrations/0001_initial.py,sha256=toNuYoHZePe5wJ6AKEW9oPOdt2OefmxDEDDJGYQIrFk,18719
95
96
  edu_rdm_integration/migrations/0002_init_data_uploadstatus.py,sha256=kht966YNuDbC3qTGrcWswJPsVuAtNO59Ck15G2eS2bU,944
96
97
  edu_rdm_integration/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
97
- edu_rdm_integration-0.4.4.dist-info/LICENSE,sha256=uw43Gjjj-1vXWCItfSrNDpbejnOwZMrNerUh8oWbq8Q,3458
98
- edu_rdm_integration-0.4.4.dist-info/METADATA,sha256=otWbiMCDrxJvEQWpBjYwSxdoWzOHFpHU9Cgxdtdm2l4,21991
99
- edu_rdm_integration-0.4.4.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
100
- edu_rdm_integration-0.4.4.dist-info/namespace_packages.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
101
- edu_rdm_integration-0.4.4.dist-info/top_level.txt,sha256=nRJV0O14UtNE-jGIYG03sohgFnZClvf57H5m6VBXe9Y,20
102
- edu_rdm_integration-0.4.4.dist-info/RECORD,,
98
+ edu_rdm_integration-0.4.6.dist-info/LICENSE,sha256=uw43Gjjj-1vXWCItfSrNDpbejnOwZMrNerUh8oWbq8Q,3458
99
+ edu_rdm_integration-0.4.6.dist-info/METADATA,sha256=FveUgd-2tRjUmx04k6gXYyDn8k3W2ej_YVllhQXA32o,22881
100
+ edu_rdm_integration-0.4.6.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
101
+ edu_rdm_integration-0.4.6.dist-info/namespace_packages.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
102
+ edu_rdm_integration-0.4.6.dist-info/top_level.txt,sha256=nRJV0O14UtNE-jGIYG03sohgFnZClvf57H5m6VBXe9Y,20
103
+ edu_rdm_integration-0.4.6.dist-info/RECORD,,