edu-rdm-integration 0.6.4__py3-none-any.whl → 0.6.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.
@@ -49,7 +49,9 @@ from edu_rdm_integration.consts import (
49
49
  REGIONAL_DATA_MART_INTEGRATION_COLLECTING_DATA,
50
50
  )
51
51
  from edu_rdm_integration.models import (
52
+ CollectingDataStageStatus,
52
53
  CollectingDataSubStageStatus,
54
+ CollectingExportedDataStage,
53
55
  CollectingExportedDataSubStage,
54
56
  RegionalDataMartModelEnum,
55
57
  )
@@ -95,6 +97,13 @@ class BaseCollectModelsData:
95
97
  # Идентификатор CollectDataCommandProgress для передачи сигналу manager_created
96
98
  self.command_id: Optional[int] = kwargs.get('command_id')
97
99
 
100
+ def _has_stage_created_or_in_progress(self, manager_id: str, model: str) -> bool:
101
+ """Проверяет есть ли готовый к работе stage или в работе для данной модели.
102
+
103
+ В общем случае разрешается параллельный сбор данных одной модели.
104
+ """
105
+ return False
106
+
98
107
  def _find_collecting_models_data_managers(self):
99
108
  """
100
109
  Поиск менеджеров Функций, которые должны быть запущены для сбора данных моделей РВД.
@@ -113,7 +122,7 @@ class BaseCollectModelsData:
113
122
  for model_enum in models:
114
123
  manager_class = collecting_models_data_managers_map.get(model_enum.key)
115
124
 
116
- if manager_class:
125
+ if manager_class and not self._has_stage_created_or_in_progress(manager_class.uuid, model_enum.key):
117
126
  self._collecting_data_managers[model_enum.key] = manager_class
118
127
 
119
128
  logger.info('collecting models data managers finished')
@@ -272,6 +281,18 @@ class BaseCollectLatestModelsData(BaseCollectModelsData):
272
281
  Сбор данных моделей РВД на основе логов за период с последней сборки до указанной даты.
273
282
  """
274
283
 
284
+ def _has_stage_created_or_in_progress(self, manager_id: str, model: str) -> bool:
285
+ """Проверяет есть ли готовый к работе stage или в работе для данной модели."""
286
+ stage_created_or_in_progress = CollectingExportedDataStage.objects.filter(
287
+ manager_id=manager_id,
288
+ status_id__in=(CollectingDataStageStatus.CREATED.key, CollectingDataStageStatus.IN_PROGRESS.key),
289
+ ).exists()
290
+
291
+ if stage_created_or_in_progress:
292
+ logger.info(f'model {model} is skipped because it is already created or in progress!')
293
+
294
+ return stage_created_or_in_progress
295
+
275
296
  def _get_last_finished_entity_upload(self) -> Dict[str, datetime]:
276
297
  """
277
298
  Возвращает словарь с uuid менеджера и датой последней успешной выгрузки по указанным сущностям.
@@ -53,6 +53,9 @@ class BaseEduLogGenerator:
53
53
  модели РВД необходимо определять в функциях.
54
54
  """
55
55
 
56
+ def _get_generate_logs_method(self, model: ModelEnumValue):
57
+ return getattr(self, f'_generate_{model.key.lower()}_logs')
58
+
56
59
  def generate(
57
60
  self,
58
61
  model: ModelEnumValue,
@@ -71,7 +74,7 @@ class BaseEduLogGenerator:
71
74
  logs_period_ended_at: конец периода формирования логов;
72
75
  school_ids: список идентификаторов школ.
73
76
  """
74
- generate_logs_method = getattr(self, f'_generate_{model.key.lower()}_logs')
77
+ generate_logs_method = self._get_generate_logs_method(model)
75
78
 
76
79
  logs = generate_logs_method(
77
80
  logs_period_started_at=logs_period_started_at,
@@ -0,0 +1,138 @@
1
+ import datetime
2
+ import decimal
3
+ import uuid
4
+ from typing import (
5
+ TYPE_CHECKING,
6
+ Any,
7
+ Dict,
8
+ Optional,
9
+ Type,
10
+ )
11
+ from unittest import (
12
+ mock,
13
+ )
14
+
15
+ from django.conf import (
16
+ settings,
17
+ )
18
+ from django.db.models.fields.files import (
19
+ FieldFile,
20
+ )
21
+ from django.test import (
22
+ TestCase,
23
+ )
24
+ from django.utils import (
25
+ timezone,
26
+ )
27
+
28
+ from educommon.audit_log.models import (
29
+ AuditLog,
30
+ Table,
31
+ )
32
+ from educommon.integration_entities.enums import (
33
+ EntityLogOperation,
34
+ )
35
+
36
+
37
+ if TYPE_CHECKING:
38
+ from django.db.models import (
39
+ Model,
40
+ )
41
+
42
+ from function_tools.managers import (
43
+ RunnerManager,
44
+ )
45
+
46
+
47
+ class BaseCollectingFunctionTestCase(TestCase):
48
+ """Базовый класс тестирования Функции сбора."""
49
+
50
+ databases = (settings.DEFAULT_DB_ALIAS, settings.SERVICE_DB_ALIAS)
51
+
52
+ @property
53
+ def manager(self) -> Type['RunnerManager']:
54
+ """Менеджер раннера Функции сбора."""
55
+ raise NotImplementedError
56
+
57
+ @classmethod
58
+ def tearDownClass(cls) -> None:
59
+ """Вызывается один раз после запуска всех тестов класса."""
60
+ cls.delete_auditlogs()
61
+
62
+ super().tearDownClass()
63
+
64
+ @staticmethod
65
+ def delete_auditlogs() -> None:
66
+ """Удаляет логи."""
67
+ AuditLog.objects.all().delete()
68
+
69
+ def setUp(self) -> None:
70
+ """Подготавливает фикстуры."""
71
+ self.now = timezone.now()
72
+
73
+ def run_collecting_function(self) -> None:
74
+ """Запускает Функцию сбора."""
75
+ runner_manager = self.manager(
76
+ logs_period_started_at=datetime.datetime.combine(self.now, datetime.time.min),
77
+ logs_period_ended_at=datetime.datetime.combine(self.now, datetime.time.max),
78
+ )
79
+ runner_manager.run()
80
+
81
+ @mock.patch('educommon.audit_log.models.AuditLog.ready_to_save')
82
+ @mock.patch('educommon.audit_log.models.AuditLog.is_read_only')
83
+ def create_auditlog(
84
+ self,
85
+ is_read_only_mock: mock.MagicMock,
86
+ ready_to_save_mock: mock.MagicMock,
87
+ *,
88
+ instance: 'Model',
89
+ changes: Optional[Dict[str, Any]] = None,
90
+ operation: EntityLogOperation = EntityLogOperation.UPDATE,
91
+ ) -> None:
92
+ """Создает AuditLog."""
93
+ is_read_only_mock.return_value = False
94
+ ready_to_save_mock.return_value = True
95
+
96
+ table = Table.objects.only('pk').get(name=instance._meta.db_table)
97
+
98
+ timestamp = datetime.datetime.combine(self.now, timezone.now().time())
99
+
100
+ if changes is None:
101
+ changes = {'__stub': None} # changes не может быть пустым
102
+ else:
103
+ changes['modified'] = timestamp.isoformat().replace('T', ' ')
104
+
105
+ AuditLog.objects.create(
106
+ user_id=1,
107
+ user_type_id=1,
108
+ ip='127.0.0.1',
109
+ data=self._clean_data(instance),
110
+ changes=changes,
111
+ table=table,
112
+ object_id=instance.pk,
113
+ time=timestamp,
114
+ operation=operation,
115
+ )
116
+
117
+ def _clean_data(self, instance: 'Model') -> Dict[str, Optional[str]]:
118
+ """Подготавливает данные экземпляра модели для формирования AuditLog'a."""
119
+ fields = {}
120
+
121
+ for key, value in vars(instance).items():
122
+ if key.startswith('_'):
123
+ continue
124
+
125
+ if isinstance(value, datetime.datetime):
126
+ fields[key] = value.strftime('%Y-%m-%d %H:%M:%S.%f%z')
127
+ elif isinstance(value, datetime.date):
128
+ fields[key] = value.strftime('%Y-%m-%d')
129
+ elif isinstance(value, bool):
130
+ fields[key] = 't' if value else 'f'
131
+ elif isinstance(value, (int, float, uuid.UUID, decimal.Decimal)):
132
+ fields[key] = str(value)
133
+ elif isinstance(value, FieldFile):
134
+ fields[key] = value.name
135
+ else:
136
+ fields[key] = value
137
+
138
+ return fields
@@ -101,7 +101,9 @@ class BaseExportDataFunction(
101
101
  )
102
102
 
103
103
  # Проставление подэтапа выгрузки
104
- self.entities[0].main_model.objects.filter(pk__in=model_ids).update(exporting_sub_stage=self._sub_stage)
104
+ self.entities[0].main_model_enum.model.objects.filter(pk__in=model_ids).update(
105
+ exporting_sub_stage=self._sub_stage,
106
+ )
105
107
 
106
108
  logger.info(f'{LOGS_DELIMITER * 3}{repr(self._sub_stage)} created.')
107
109
 
@@ -177,7 +177,7 @@ class BaseExportEntitiesData:
177
177
  manager_class = exporting_entities_data_managers_map.get(entity_enum.key)
178
178
 
179
179
  if manager_class and not self._has_stage_created_or_in_progress(manager_class.uuid, entity_enum.key):
180
- self.manager_main_model_map[manager_class.uuid] = entity_enum.main_model
180
+ self.manager_main_model_map[manager_class.uuid] = entity_enum.main_model_enum.model
181
181
  self._exporting_data_managers.add(manager_class)
182
182
 
183
183
  logger.info('finding exporting entities data manager finished.')
@@ -87,7 +87,7 @@ class BaseFirstExportEntitiesDataCommandsGenerator:
87
87
 
88
88
  for entity in self.entities:
89
89
  ordered_rows_queries_sql = self.ordered_rows_query.format(
90
- table_name=entity.main_model._meta.db_table,
90
+ table_name=entity.main_model_enum.model._meta.db_table,
91
91
  period_started_at=self.period_started_at.strftime(consts.DATE_FORMAT),
92
92
  period_ended_at=self.period_ended_at.strftime(consts.DATE_FORMAT),
93
93
  )
@@ -2,6 +2,9 @@ import uuid
2
2
  from datetime import (
3
3
  datetime,
4
4
  )
5
+ from typing import (
6
+ List,
7
+ )
5
8
 
6
9
  import django.utils.timezone
7
10
  from django.contrib.postgres.fields import (
@@ -633,7 +636,17 @@ class RegionalDataMartModelEnum(TitledModelEnum):
633
636
 
634
637
 
635
638
  class RegionalDataMartEntityEnum(TitledModelEnum):
636
- """Модель-перечисление сущностей выгрузки в Региональная витрина данных."""
639
+ """Модель-перечисление сущностей выгрузки в Региональная витрина данных.
640
+
641
+ Поля:
642
+ entity - data-класс сущности;
643
+ main_model_enum - значение модели-перечисления RegionalDataMartModelEnum основной модели РВД для формирования
644
+ данных сущности. Обычно это модель идентификаторы записей которой соответствуют идентификаторам в записях
645
+ сущности. У этих записей проставляется подэтап выгрузки данных;
646
+ additional_model_enums - кортеж значений модели-перечисления RegionalDataMartModelEnum с дополнительными
647
+ моделями РВД, которые участвуют в формировании записей сущностей. Они показывают, что перед запуском
648
+ экспорта данных сущности по ним и основной модели должен быть запущен сбор данных.
649
+ """
637
650
 
638
651
  class Meta:
639
652
  db_table = 'rdm_entity'
@@ -641,6 +654,45 @@ class RegionalDataMartEntityEnum(TitledModelEnum):
641
654
  verbose_name = 'Модель-перечисление сущностей "Региональной витрины данных"'
642
655
  verbose_name_plural = 'Модели-перечисления сущностей "Региональной витрины данных"'
643
656
 
657
+ @property
658
+ def model_enums(self):
659
+ """Возвращает модели, от которых зависит сущность."""
660
+ value = self.model_enum_value
661
+
662
+ return self.get_model_enums_from_value(value=value)
663
+
664
+ @staticmethod
665
+ def get_model_enums_from_value(value: ModelEnumValue):
666
+ """Получение значений модели-перечисления моделей по значению модели-перечисления сущностей."""
667
+ model_enums = [value.main_model_enum, *value.additional_model_enums]
668
+
669
+ return model_enums
670
+
671
+ @classmethod
672
+ def get_entities_model_enums(
673
+ cls,
674
+ entity_enums: List[ModelEnumValue],
675
+ is_sorted: bool = True,
676
+ ) -> List[ModelEnumValue]:
677
+ """Получение списка значений модели-перечисления моделей RegionalDataMartModelEnum.
678
+
679
+ Args:
680
+ entity_enums: Список значений модели-перечисления сущностей RegionalDataMartEntityEnum;
681
+ is_sorted: Необходимость сортировки значений модели-перечисления RegionalDataMartModelEnum по полю
682
+ order_number.
683
+ """
684
+ model_enums = set()
685
+
686
+ for entity_enum_value in entity_enums:
687
+ model_enums.update(cls.get_model_enums_from_value(value=entity_enum_value))
688
+
689
+ model_enums = list(model_enums)
690
+
691
+ if is_sorted:
692
+ model_enums = sorted(model_enums, key=lambda value: value.order_number)
693
+
694
+ return model_enums
695
+
644
696
 
645
697
  class AbstractCollectDataCommandProgress(ReprStrPreModelMixin, BaseObjectModel):
646
698
  """
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: edu-rdm-integration
3
- Version: 0.6.4
3
+ Version: 0.6.6
4
4
  Summary: Интеграция с Региональной витриной данных
5
5
  Home-page:
6
6
  Download-URL:
@@ -16,6 +16,10 @@ Classifier: Programming Language :: Python :: 3.8
16
16
  Classifier: Programming Language :: Python :: 3.9
17
17
  Classifier: Intended Audience :: Developers
18
18
  Classifier: Environment :: Console
19
+ Classifier: Framework :: Django :: 1.11
20
+ Classifier: Framework :: Django :: 2.0
21
+ Classifier: Framework :: Django :: 2.1
22
+ Classifier: Framework :: Django :: 2.2
19
23
  Description-Content-Type: text/markdown
20
24
  License-File: LICENSE
21
25
  Requires-Dist: packaging <24,>=21.3
@@ -23,9 +27,10 @@ Requires-Dist: pip <24,>=20.1.1
23
27
  Requires-Dist: setuptools <69,>=47.3.1
24
28
  Requires-Dist: wheel <0.42,>=0.37.1
25
29
  Requires-Dist: transliterate <2
30
+ Requires-Dist: Django <2.3,>=1.11
26
31
  Requires-Dist: educommon <4,>=3.0.0
27
32
  Requires-Dist: function-tools <1,>=0.5.0
28
- Requires-Dist: m3-db-utils <1,>=0.3.4
33
+ Requires-Dist: m3-db-utils <1,>=0.3.6
29
34
  Requires-Dist: uploader-client <1,>=0.1.12
30
35
 
31
36
  # Проект "Интеграция с Региональной витриной данных (РВД)"
@@ -102,6 +107,7 @@ Requires-Dist: uploader-client <1,>=0.1.12
102
107
  ('rdm_transfer_task', 'HOUR'): '*/4',
103
108
  ('rdm_transfer_task', 'TRANSFER_TASK_DAY_OF_WEEK'): '*',
104
109
  ('rdm_transfer_task', 'TIMEDELTA'): 3600,
110
+ ('rdm_transfer_task', 'ENTITIES'): '',
105
111
  ('rdm_upload_status_task', 'MINUTE'): '*/30',
106
112
  ('rdm_upload_status_task', 'HOUR'): '*',
107
113
  ('rdm_upload_status_task', 'DAY_OF_WEEK'): '*',
@@ -136,6 +142,8 @@ Requires-Dist: uploader-client <1,>=0.1.12
136
142
  RDM_TRANSFER_TASK_HOUR = conf.get('rdm_transfer_task', 'HOUR')
137
143
  RDM_TRANSFER_TASK_DAY_OF_WEEK = conf.get('rdm_transfer_task', 'DAY_OF_WEEK')
138
144
  RDM_TRANSFER_TASK_TIMEDELTA = conf.get_int('rdm_transfer_task', 'TIMEDELTA')
145
+ # Сущности, по которым должен производиться сбор и выгрузка данных
146
+ RDM_TRANSFER_TASK_ENTITIES = conf.get_tuple('rdm_transfer_task', 'ENTITIES') or ()
139
147
 
140
148
  # Настройка запуска периодической задачи статуса загрузки данных в витрину:
141
149
  RDM_UPLOAD_STATUS_TASK_MINUTE = conf.get('rdm_upload_status_task', 'MINUTE')
@@ -182,6 +190,7 @@ Requires-Dist: uploader-client <1,>=0.1.12
182
190
  | RDM_TRANSFER_TASK_HOUR | Настройка запуска периодической задачи выгрузки данных. Час | '*/4' |
183
191
  | RDM_TRANSFER_TASK_DAY_OF_WEEK | Настройка запуска периодической задачи выгрузки данных. День недели | '*' |
184
192
  | RDM_TRANSFER_TASK_TIMEDELTA | Дельта между предыдущим и следующим запуском периодической задачи в секундах | 3600 |
193
+ | RDM_TRANSFER_TASK_ENTITIES | Сущности, по которым должен производиться сбор и выгрузка данных | '' |
185
194
  | RDM_UPLOAD_STATUS_TASK_MINUTE | Настройка запуска периодической задачи статуса загрузки данных в витрину. Минута | '*/30' |
186
195
  | RDM_UPLOAD_STATUS_TASK_HOUR | Настройка запуска периодической задачи статуса загрузки данных в витрину. Час | '*' |
187
196
  | RDM_UPLOAD_STATUS_TASK_DAY_OF_WEEK | Настройка запуска периодической задачи статуса загрузки данных в витрину. День недели | '*' |
@@ -209,6 +218,8 @@ Requires-Dist: uploader-client <1,>=0.1.12
209
218
  DAY_OF_WEEK=*
210
219
  # Дельта между прошлым и текущим запуском, сек
211
220
  TIMEDELTA=120
221
+ # Сущности, по которым должен производиться сбор и выгрузка данных. Перечисляются через запятую без пробелов.
222
+ ENTITIES =
212
223
 
213
224
  # Настройка запуска периодической задачи статуса загрузки данных в витрину
214
225
  [rdm_upload_status_task]
@@ -279,6 +290,37 @@ Requires-Dist: uploader-client <1,>=0.1.12
279
290
  ### Удалено
280
291
 
281
292
 
293
+ ## [0.6.6] - 2023-10-16
294
+
295
+ Добавлен базовый класс для тестирования Функций сбора, добавлена явная зависимость Django.
296
+
297
+ ### Добавлено
298
+
299
+ - [EDUSCHL-20684](https://jira.bars.group/browse/EDUSCHL-20684)
300
+ PATCH - Базовый класс для тестирования Функций сбора;
301
+ - [EDUSCHL-20684](https://jira.bars.group/browse/EDUSCHL-20684)
302
+ PATCH - Добавлена зависимость Django.
303
+
304
+
305
+ ## [0.6.5] - 2023-10-11
306
+
307
+ Получение метода генерации логов вынесено в отдельный метод для избавления от необходимости хранить все методы в одном классе.
308
+
309
+ ### Исправлено
310
+
311
+ - [EDUCLLG-7634](https://jira.bars.group/browse/EDUCLLG-7634)
312
+ PATCH - Получение метода генерации логов вынесено в отдельный метод для избавления от необходимости хранить все методы в одном классе;
313
+
314
+ - [EDUSCHL-20571](https://jira.bars.group/browse/EDUSCHL-20571)
315
+ PATCH - При сборе актуальных данных моделей отслеживаются уже запущенные сборы и новый сбор по модели не запускается.
316
+
317
+ - [EDUSCHL-20571](https://jira.bars.group/browse/EDUSCHL-20571)
318
+ PATCH - Указание назначения полей модели-перечисления сущностей RegionalDataMartEntityEnum;
319
+
320
+ - [EDUSCHL-20571](https://jira.bars.group/browse/EDUSCHL-20571)
321
+ PATCH - Добавление возможности получения значений модели-перечисления RegionalDataMartEntityEnum моделей РВД для указанных сущностей.
322
+
323
+
282
324
  ## [0.6.4] - 2023-10-09
283
325
 
284
326
  Исправлена ошибка сборки, из-за которой файлы шаблонов *.py-tpl не попадали в пакет.
@@ -288,6 +330,7 @@ Requires-Dist: uploader-client <1,>=0.1.12
288
330
  - [EDUCLLG-7634](https://jira.bars.group/browse/EDUCLLG-7634)
289
331
  PATCH - Добавлено включение шаблонов *.py-tpl в пакет при сборке.
290
332
 
333
+
291
334
  ## [0.6.3] - 2023-10-05
292
335
 
293
336
  Доработка модели AbstractCollectDataCommandProgress и класса BaseFirstCollectModelsDataCommandsGenerator.
@@ -341,7 +384,7 @@ Requires-Dist: uploader-client <1,>=0.1.12
341
384
 
342
385
  ## [0.5.8] - 2023-09-13
343
386
 
344
- Исправлена ошибка добавления в описание асинхронной задачи списка выгруженных сущностей
387
+ Исправлена ошибка добавления в описание асинхронной задачи списка выгруженных сущностей
345
388
  BaseExportLatestEntitiesData._set_description_to_async_task.
346
389
 
347
390
  ### Исправлено
@@ -373,8 +416,8 @@ BaseExportLatestEntitiesData._set_description_to_async_task.
373
416
  - [EDUSCHL-20435](https://jira.bars.group/browse/EDUSCHL-20435)
374
417
  PATCH - Исправлено нахождение левой границы в классе ExportLatestEntitiesData;
375
418
  - Добавлена проверка на наличие запущенных или готовых к выгрузке сущностей;
376
- - Добавлен параметр update_modified, который обновляет поле modified у собранных моделей,
377
- чтобы выгрузить невыгруженные записи.
419
+ - Добавлен параметр update_modified, который обновляет поле modified у собранных моделей,
420
+ чтобы выгрузить невыгруженные записи.
378
421
 
379
422
 
380
423
  ## [0.5.5] - 2023-09-04
@@ -427,14 +470,14 @@ split_by_days_count переименовал в split_by_quantity.
427
470
  - [EDUSCHL-20227](https://jira.bars.group/browse/EDUSCHL-20227)
428
471
  PATCH Если у сущности не заполнен creating_trigger_models, то в генераторе BaseFirstCollectModelsDataCommandsGenerator
429
472
  не формируется словарь с параметрами для команды.
430
-
473
+
431
474
  - [EDUSCHL-20229](https://jira.bars.group/browse/EDUSCHL-20229)
432
475
  PATCH Если у сущности не заполнен creating_trigger_models, то в генераторе BaseFirstCollectModelsDataCommandsGenerator
433
476
  не формируется словарь с параметрами для команды.
434
477
 
435
478
 
436
479
  ## [0.5.0] - 2023-08-19
437
-
480
+
438
481
  Дополнительная функциональность WebEduEntityValueCache была перенесена в EntityCache в function_tools.
439
482
 
440
483
  ### Удалено
@@ -5,7 +5,7 @@ edu_rdm_integration/consts.py,sha256=chOsPOOY4_JLzN-8idg-VjbLWSlp6r3maFWqnvUsapg
5
5
  edu_rdm_integration/entities.py,sha256=mI48GExfRrQZsyg8leGJDaiy8Cmf3vlkIttNq2OYJZI,9117
6
6
  edu_rdm_integration/enums.py,sha256=fnDPz6pwOYWS6vp65IAExbpDzn2q9U3_9GGyuf4B468,4876
7
7
  edu_rdm_integration/mapping.py,sha256=bwa2fJCbV4YjQcAgRrgT3hgM6dJhr_uBtQgx3L3F2Ck,473
8
- edu_rdm_integration/models.py,sha256=agBoepF0YScpfxo3VZWvw6uy707IteT8CQVJmpUt7M4,22207
8
+ edu_rdm_integration/models.py,sha256=eUlR0DUIXcvr2yy_b0GZA6Jv__X9_iWyUsJhDMKwFDk,24976
9
9
  edu_rdm_integration/signals.py,sha256=3eRlpkDcFCF6TN80-QM8yBYLcyozzcmoPjz6r4_ApWg,73
10
10
  edu_rdm_integration/storages.py,sha256=o5WqUG7SnkeuMt-z8spUi-IraivST-7KHzfY-M3v7FA,6807
11
11
  edu_rdm_integration/utils.py,sha256=CgFrW1mEQim3wcCX6q9o9mvIm79ASQ92HojXyuN3dc0,5558
@@ -27,9 +27,10 @@ edu_rdm_integration/adapters/strings.py,sha256=-k9dex8A7hCpkzUkudVkKRAbNRuuqog2h
27
27
  edu_rdm_integration/adapters/tests.py,sha256=MoRY-a75Ow-7EjeQYxkXWunwqTGuBMaUyEkEV2oy05I,59
28
28
  edu_rdm_integration/adapters/validators.py,sha256=LJWnCY8PtXDOj-fm3fBWjQYsHsSLfyKf_D97pqPv73s,496
29
29
  edu_rdm_integration/collect_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
- edu_rdm_integration/collect_data/collect.py,sha256=3sicEiX9v_EQtd5vFOyclSV-kYNV7FNxx09DdyIWIAk,12843
31
- edu_rdm_integration/collect_data/generators.py,sha256=lmXbptKxirEXw8yEYyFf3tRTjmg_zzbQn8Ox76cxAuY,8870
30
+ edu_rdm_integration/collect_data/collect.py,sha256=LokNsirTCRBUmzwZAW9d_n8bek_DDKVYzdU12h3xRhE,14040
31
+ edu_rdm_integration/collect_data/generators.py,sha256=DA5EQ4xvIE-xe-H1RFTku3BfHZtCSVe_UCUx4qWB9D0,8988
32
32
  edu_rdm_integration/collect_data/helpers.py,sha256=EftJ8R-tn1r7Y_P6tGZmqxJ9-g89m12p9kA8NYmwwbQ,3009
33
+ edu_rdm_integration/collect_data/tests.py,sha256=7ergphTxnPgoI5XQMOFcW_y5Jy4ILWJkWlNbNDJF6_A,4080
33
34
  edu_rdm_integration/collect_data/base/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
35
  edu_rdm_integration/collect_data/base/caches.py,sha256=3BaJxYBk9fi0aiAVzym-Jz8aNP1eSOqh4Y8OVw1HnSg,763
35
36
  edu_rdm_integration/collect_data/base/functions.py,sha256=HT23EyiD-H50p4NLx2_LtioktTHHFVLRmAgWdbuHErw,2379
@@ -70,8 +71,8 @@ edu_rdm_integration/collect_data/non_calculated/base/tests.py,sha256=MoRY-a75Ow-
70
71
  edu_rdm_integration/collect_data/non_calculated/base/validators.py,sha256=0YvnfrfK1iFcZVSB-M-Xv82tIjYxEU_BwLofAEuGVW4,973
71
72
  edu_rdm_integration/export_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
72
73
  edu_rdm_integration/export_data/consts.py,sha256=Z6Uho8oViMc0t1tyQFZfrPFBwPx6KnhUf_iZ0qgob8o,16
73
- edu_rdm_integration/export_data/export.py,sha256=jqJYXg-Vm_IwkOxposZKk5QY8d4aBhNmGJOw4PRFJjk,14935
74
- edu_rdm_integration/export_data/generators.py,sha256=huonSRK5arfBzU09BnLAHC7AsSFYU0sCz5utCtejdJk,3950
74
+ edu_rdm_integration/export_data/export.py,sha256=xr3_oTnufS_NMgJLPIeL87fNkt7zOVA5rM44sB3QvEw,14946
75
+ edu_rdm_integration/export_data/generators.py,sha256=GwEvuA841Fp2JITkR_jN1b42sRAZOBW-9kApIm_6Q94,3961
75
76
  edu_rdm_integration/export_data/helpers.py,sha256=hU346RmQ17Ra2etFvxXI7JQlLyp_0KxH1jm-eeCqejc,2933
76
77
  edu_rdm_integration/export_data/strategies.py,sha256=ocHskG-x54U-ESX56OlZPgOibkGkuv7VKmK7hVmqj_0,6725
77
78
  edu_rdm_integration/export_data/base/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -79,7 +80,7 @@ edu_rdm_integration/export_data/base/caches.py,sha256=dj8LGB7TMtX3cSfp-1UB3dnzcT
79
80
  edu_rdm_integration/export_data/base/consts.py,sha256=jLuy2y7YQ921OrEuzDld3F0k6YxgCnr5yorWBQJiLLw,519
80
81
  edu_rdm_integration/export_data/base/enums.py,sha256=BSmwrkzYwEQhz9NbZCJsldY532PqgZJzxzsVk6ue0bM,93
81
82
  edu_rdm_integration/export_data/base/errors.py,sha256=SaxXgKWNGG8RZQ8soFlzbX8d2_j58gWVmikzNZG1s74,291
82
- edu_rdm_integration/export_data/base/functions.py,sha256=diZq-a5LuBGt1oBJnJpRM7hu-UtbmmUfVjwijM6HOXs,12071
83
+ edu_rdm_integration/export_data/base/functions.py,sha256=hX6n4-Wum04w7DNa8M5Yy5Z-vwNi492F4cjx7n_YTsw,12105
83
84
  edu_rdm_integration/export_data/base/helpers.py,sha256=t2VLuvI8s84ZAVVnRLmV8jjYqSkn8hflfpgkQqzKJ3Q,3375
84
85
  edu_rdm_integration/export_data/base/managers.py,sha256=RuItunDuKIql065Xen6BSl_EEI8PHR9XeEyCDNgPBCg,6714
85
86
  edu_rdm_integration/export_data/base/presenters.py,sha256=JXh8nwyezaC-2h_TYfPPYUZRitFr9Y9Ifp-j7CaUCL0,403
@@ -128,9 +129,9 @@ edu_rdm_integration/management/commands/export_entities_data.py,sha256=Mas1zwsH-
128
129
  edu_rdm_integration/migrations/0001_initial.py,sha256=toNuYoHZePe5wJ6AKEW9oPOdt2OefmxDEDDJGYQIrFk,18719
129
130
  edu_rdm_integration/migrations/0002_init_data_uploadstatus.py,sha256=kht966YNuDbC3qTGrcWswJPsVuAtNO59Ck15G2eS2bU,944
130
131
  edu_rdm_integration/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
131
- edu_rdm_integration-0.6.4.dist-info/LICENSE,sha256=uw43Gjjj-1vXWCItfSrNDpbejnOwZMrNerUh8oWbq8Q,3458
132
- edu_rdm_integration-0.6.4.dist-info/METADATA,sha256=yCoz_cf0eqYGvAPMZX0xY8iXukpCLZVO32nYf-qWwV0,34834
133
- edu_rdm_integration-0.6.4.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
134
- edu_rdm_integration-0.6.4.dist-info/namespace_packages.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
135
- edu_rdm_integration-0.6.4.dist-info/top_level.txt,sha256=nRJV0O14UtNE-jGIYG03sohgFnZClvf57H5m6VBXe9Y,20
136
- edu_rdm_integration-0.6.4.dist-info/RECORD,,
132
+ edu_rdm_integration-0.6.6.dist-info/LICENSE,sha256=uw43Gjjj-1vXWCItfSrNDpbejnOwZMrNerUh8oWbq8Q,3458
133
+ edu_rdm_integration-0.6.6.dist-info/METADATA,sha256=9__jYHSUtU3cPZY65i-5ckdPpZUVpRZ725spfS1EqJA,37636
134
+ edu_rdm_integration-0.6.6.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
135
+ edu_rdm_integration-0.6.6.dist-info/namespace_packages.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
136
+ edu_rdm_integration-0.6.6.dist-info/top_level.txt,sha256=nRJV0O14UtNE-jGIYG03sohgFnZClvf57H5m6VBXe9Y,20
137
+ edu_rdm_integration-0.6.6.dist-info/RECORD,,