edu-rdm-integration 3.6.0__py3-none-any.whl → 3.8.0__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.
@@ -0,0 +1,3 @@
1
+ NOT_SPECIFIED_QUEUE_TO_MODEL_ERROR = 'Для переданной модели {} не указана очередь для сохранения!'
2
+
3
+ CACHED_OBJECTS_TYPE_MISMATCH_ERROR = 'Тип сравниваемого объекта не соответствует типу объекта в кеше'
@@ -1,3 +1,10 @@
1
+ from abc import (
2
+ ABCMeta,
3
+ abstractmethod,
4
+ )
5
+ from copy import (
6
+ deepcopy,
7
+ )
1
8
  from typing import (
2
9
  TYPE_CHECKING,
3
10
  Any,
@@ -25,10 +32,17 @@ from educommon.integration_entities.consts import (
25
32
  from educommon.integration_entities.enums import (
26
33
  EntityLogOperation,
27
34
  )
35
+ from educommon.integration_entities.helpers import (
36
+ EntitySaver,
37
+ )
28
38
 
29
39
  from edu_rdm_integration.collect_data.base.caches import (
30
40
  LogChange,
31
41
  )
42
+ from edu_rdm_integration.collect_data.base.consts import (
43
+ CACHED_OBJECTS_TYPE_MISMATCH_ERROR,
44
+ NOT_SPECIFIED_QUEUE_TO_MODEL_ERROR,
45
+ )
32
46
  from edu_rdm_integration.helpers import (
33
47
  Graph,
34
48
  )
@@ -41,8 +55,15 @@ from edu_rdm_integration.utils import (
41
55
 
42
56
 
43
57
  if TYPE_CHECKING:
58
+ from edu_rdm_integration.adapters.caches import (
59
+ WebEduEntityCache,
60
+ )
44
61
  from edu_rdm_integration.collect_data.base.caches import (
45
62
  IgnoreLogDependency,
63
+ LogChange,
64
+ )
65
+ from edu_rdm_integration.models import (
66
+ BaseEntityModel,
46
67
  )
47
68
 
48
69
 
@@ -216,3 +237,189 @@ class BaseIgnoreLogMixin:
216
237
  id__in=self.logs[log_model._meta.label],
217
238
  ).values_list('pk', flat=True)
218
239
  self._exclude_logs(log_model._meta.label, ignore_model_ids)
240
+
241
+
242
+ class FilteredSaveEntitiesFunctionMixin(metaclass=ABCMeta):
243
+ """
244
+ Миксин, реализующий фильтрацию объектов перед сохранением.
245
+
246
+ Предназначен для использования в классах, которые занимаются сохранением сущностей, но при этом хотят исключить
247
+ неизменённые объекты из операции записи, чтобы избежать лишних действий или запросов к базе данных.
248
+ Для работы требует реализации абстрактного свойства `_model_to_cache_map` и `_model_to_save_queue_map`, которое
249
+ определяет, какие сущности и с каким кешем нужно обработать.
250
+
251
+ Attributes:
252
+ _filtered_operations (tuple[EntityLogOperation]): : Операции, подлежащие фильтрации (по умолчанию только UPDATE).
253
+ _saved_entities_to_cache_map (dict[type[BaseEntityModel], WebEduEntityCache]): Копия маппинга моделей на кэши,
254
+ используемая для сравнения изменений.
255
+ _ignored_fields (dict[EntityLogOperation, tuple[str]]): Словарь полей, которые следует игнорировать при
256
+ сравнении для каждой операции.
257
+ """
258
+
259
+ _filtered_operations: tuple[EntityLogOperation, ...] = (EntityLogOperation.UPDATE,)
260
+ _saved_entities_to_cache_map: dict[type['BaseEntityModel'], 'WebEduEntityCache'] = {}
261
+ _ignored_fields = {
262
+ EntityLogOperation.UPDATE: ('modified', 'operation', 'collecting_sub_stage', 'exporting_sub_stage'),
263
+ }
264
+
265
+ def _is_object_to_save(
266
+ self,
267
+ saved_object: 'BaseEntityModel',
268
+ ignore_fields: Optional[Iterable[str]] = None
269
+ ) -> bool:
270
+ """
271
+ Проверяет, должен ли объект быть добавлен в очередь на сохранение.
272
+
273
+ Args:
274
+ saved_object ('BaseEntityModel'): Объект, который предполагается сохранить.
275
+ ignore_fields (Optional[Iterable[str]]): Дополнительные поля, которые нужно игнорировать.
276
+
277
+ Returns:
278
+ bool: True, если объект был изменён и его нужно сохранить, иначе False.
279
+ """
280
+ save_object_type = type(saved_object)
281
+ cache = self._saved_entities_to_cache_map.get(save_object_type)
282
+
283
+ modified = True
284
+
285
+ if cache and saved_object.pk:
286
+ original_object = cache.get(id=saved_object.pk)
287
+
288
+ if original_object:
289
+ modified = self._is_save_object_modified(saved_object, original_object, ignore_fields)
290
+
291
+ return modified
292
+
293
+ def _is_save_object_modified(
294
+ self,
295
+ saved_object: 'BaseEntityModel',
296
+ original_object: 'BaseEntityModel',
297
+ ignore_fields: Optional[Iterable[str]] = None
298
+ ) -> bool:
299
+ """
300
+ Проверяет, были ли изменения в указанном объекте относительно оригинала.
301
+
302
+ Args:
303
+ saved_object ('BaseEntityModel'): Объект, который предполагается сохранить.
304
+ original_object ('BaseEntityModel'): Оригинальное значение из кэша.
305
+ ignore_fields (Optional[Iterable[str]]): Поля, которые следует игнорировать при сравнении.
306
+
307
+ Returns:
308
+ bool: True, если объект был изменён, иначе False.
309
+ """
310
+ if not isinstance(saved_object, type(original_object)):
311
+ raise ValueError(CACHED_OBJECTS_TYPE_MISMATCH_ERROR)
312
+
313
+ if saved_object.operation == EntityLogOperation.DELETE:
314
+ return True
315
+
316
+ if ignore_fields is None:
317
+ ignore_fields = []
318
+
319
+ # Сравниваем поля объектов
320
+ for field in original_object._meta.fields:
321
+ field_name = field.name
322
+
323
+ # Пропускаем игнорируемые поля
324
+ if field_name in ignore_fields:
325
+ continue
326
+
327
+ # Получаем текущее значение поля из измененного объекта
328
+ current_value = getattr(saved_object, field_name)
329
+
330
+ # Получаем оригинальное значение поля из кеша
331
+ original_value = getattr(original_object, field_name)
332
+
333
+ # Сравниваем значения
334
+ if current_value != original_value:
335
+ return True
336
+
337
+ # Если все поля совпадают, объект не изменился
338
+ return False
339
+
340
+ def _before_prepare(self, *args, **kwargs):
341
+ """
342
+ Подготовительный этап перед началом обработки объектов.
343
+
344
+ Сохраняет копию текущих сопоставлений объектов и кэшей, чтобы обеспечить чистое состояние для последующего
345
+ сравнения.
346
+ """
347
+ self._saved_entities_to_cache_map = {
348
+ model: deepcopy(cache)
349
+ for model, cache in self._model_to_cache_map.items()
350
+ }
351
+
352
+ super()._before_prepare(*args, **kwargs)
353
+
354
+ @property
355
+ @abstractmethod
356
+ def _model_to_cache_map(self) -> dict[type['BaseEntityModel'], 'WebEduEntityCache']:
357
+ """
358
+ Абстрактное свойство, возвращающее соответствие между типами моделей и их кэшами.
359
+
360
+ Должно быть реализовано в дочернем классе. Используется для получения оригинальных данных объектов
361
+ перед сравнением.
362
+
363
+ Returns:
364
+ dict[type[BaseEntityModel], WebEduEntityCache]: Словарь, где ключ — это тип модели, а значение —
365
+ соответствующий кэш этой модели.
366
+ """
367
+
368
+ @property
369
+ @abstractmethod
370
+ def _model_to_save_queue_map(self) -> dict[type['BaseEntityModel'], dict]:
371
+ """
372
+ Абстрактное свойство, возвращающее соответствие между типами моделей и очередями сохранения.
373
+
374
+ Должно быть реализовано в дочернем классе. Используется для определения, в какую очередь будет добавляться
375
+ объект для сохранения.
376
+
377
+ Returns:
378
+ dict[type[BaseEntityModel], dict]: Словарь, где ключ — это тип модели, а значение — словарь, представляющий
379
+ очередь сохранения для этой модели.
380
+ """
381
+
382
+ def _add_to_save_entities(
383
+ self,
384
+ save_object: 'BaseEntityModel',
385
+ operation: EntityLogOperation,
386
+ ):
387
+ """Добавление в очередь сущности на сохранение."""
388
+ try:
389
+ to_save_queue: dict[
390
+ EntityLogOperation, dict[int, 'BaseEntityModel']
391
+ ] = self._model_to_save_queue_map[type(save_object)]
392
+ except KeyError:
393
+ raise KeyError(NOT_SPECIFIED_QUEUE_TO_MODEL_ERROR.format(save_object._meta.model_name))
394
+
395
+ save_object.operation = operation
396
+ save_object.collecting_sub_stage = self._sub_stage
397
+
398
+ if operation == EntityLogOperation.CREATE:
399
+ to_save_queue[EntityLogOperation.CREATE][save_object.id] = save_object
400
+ elif operation in {EntityLogOperation.UPDATE, EntityLogOperation.DELETE}:
401
+ if self._is_object_to_save(save_object, self._ignored_fields.get(operation)):
402
+ to_save_queue[EntityLogOperation.UPDATE][save_object.id] = save_object
403
+
404
+ def _get_entity_saver(self, model: 'BaseEntityModel') -> EntitySaver:
405
+ """
406
+ Возвращает экземпляр saver'а для указанной модели.
407
+
408
+ Args:
409
+ model (BaseEntityModel): Тип модели, для которой требуется получить saver.
410
+
411
+ Returns:
412
+ EntitySaver: Объект, отвечающий за сохранение сущностей указанного типа.
413
+ """
414
+ to_save_queue = self._model_to_save_queue_map[model]
415
+ return EntitySaver(to_save_entities=to_save_queue, model=model)
416
+
417
+ def _save_entities(self):
418
+ """
419
+ Выполняет сохранение всех отфильтрованных и подготовленных объектов.
420
+
421
+ Перебирает все модели из `_model_to_save_queue_map` и вызывает соответствующий `EntitySaver`.
422
+ """
423
+ for model in self._model_to_save_queue_map:
424
+ entity_saver = self._get_entity_saver(model)
425
+ entity_saver()
@@ -58,7 +58,6 @@ from edu_rdm_integration.models import (
58
58
  ExportingDataStageStatus,
59
59
  ExportingDataSubStageStatus,
60
60
  ExportingDataSubStageUploaderClientLog,
61
- UploadDataCommand,
62
61
  UploadStatusRequestLog,
63
62
  )
64
63
  from edu_rdm_integration.redis_cache import (
@@ -321,7 +320,7 @@ class Graph:
321
320
 
322
321
 
323
322
  def save_command_log_link(
324
- command: Union[AbstractExportDataCommandProgress, UploadDataCommand],
323
+ command: AbstractExportDataCommandProgress,
325
324
  log_dir: str
326
325
  ) -> None:
327
326
  """Сохраняет ссылку на лог команды."""
@@ -0,0 +1,16 @@
1
+ # Generated by Django 3.2.24 on 2025-05-07 19:50
2
+
3
+ from django.db import migrations
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('edu_rdm_integration', '0016_transferredentity_queue_level'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.DeleteModel(
14
+ name='UploadDataCommand',
15
+ ),
16
+ ]
@@ -969,42 +969,3 @@ class ExportingDataSubStageEntity(BaseObjectModel):
969
969
  db_table = 'rdm_exporting_data_sub_stage_entity'
970
970
  verbose_name = 'Связь сущности и подэтапа выгрузки'
971
971
  verbose_name_plural = 'Связи сущности и подэтапа выгрузки'
972
-
973
-
974
- class UploadDataCommand(ReprStrPreModelMixin, BaseObjectModel):
975
- """Модель, хранящая данные для формирования и отслеживания асинхронной задачи по отправке данных в витрину."""
976
-
977
- task = ForeignKey(
978
- to='async_task.RunningTask',
979
- verbose_name='Асинхронная задача',
980
- blank=True,
981
- null=True,
982
- on_delete=SET_NULL,
983
- )
984
- logs_link = FileField(
985
- upload_to=get_data_command_progress_attachment_path,
986
- max_length=255,
987
- verbose_name='Ссылка на файл логов',
988
- )
989
- type = PositiveSmallIntegerField( # noqa: A003
990
- verbose_name='Тип команды',
991
- choices=CommandType.get_choices(),
992
- )
993
- entity = ForeignKey(
994
- to=RegionalDataMartEntityEnum,
995
- verbose_name='Сущность РВД',
996
- on_delete=PROTECT,
997
- )
998
- created = DateTimeField(
999
- verbose_name='Дата создания',
1000
- default=timezone.now,
1001
- )
1002
- generation_id = UUIDField(
1003
- 'Идентификатор генерации',
1004
- default=uuid.uuid4,
1005
- )
1006
-
1007
- class Meta:
1008
- db_table = 'rdm_upload_data_command'
1009
- verbose_name = 'Команда отправки данных в витрину'
1010
- verbose_name_plural = 'Команды отправки данных в витрину'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: edu-rdm-integration
3
- Version: 3.6.0
3
+ Version: 3.8.0
4
4
  Summary: Интеграция с Региональной витриной данных
5
5
  Author-email: BARS Group <education_dev@bars.group>
6
6
  Project-URL: Homepage, https://stash.bars-open.ru/projects/EDUBASE/repos/edu_rdm_integration/browse
@@ -79,7 +79,7 @@ Dynamic: license-file
79
79
  Стоит обратить внимание, что сущности РВД могут содержать в себе данные из нескольких моделей РВД.
80
80
 
81
81
  Очереди для периодических задач сборки и выгрузки данных
82
- : Важно учитывать, что с версии пакета 3.6 вводится две новые очереди и соответсвущие этим очередям периодические задачи
82
+ : Важно учитывать, что с версии пакета 3.6 вводится две новые очереди и соответствущие этим очередям периодические задачи
83
83
  сбора и выгрузки данных. Очередь для сущности указывается в реестре "Сущности для сбора и экспорта данных" - по умолчанию все
84
84
  сущности относятся к основной очереди.
85
85
  Итого - нужно настроить три очереди для работы.
@@ -142,8 +142,36 @@ Dynamic: license-file
142
142
  ('uploader_client', 'ENABLE_REQUEST_EMULATION'): False,
143
143
  })
144
144
  ```
145
- С версии пакета 3.6 добавляются новые настройки для двух периодических задач разных очередей сбора и выгрузки данных
146
- ```
145
+ Дополнительные настройки с версии 3.4.2
146
+ ```
147
+ PROJECT_DEFAULT_CONFIG.update({
148
+ # Настройки РВД
149
+ ('rdm_general', 'EXPORT_ENTITY_ID_PREFIX'): '', # Дефолтное значение нужно изменить на специфическое системе
150
+ ('rdm_general', 'COLLECT_CHUNK_SIZE'): 500,
151
+ ('rdm_general', 'EXPORT_CHUNK_SIZE'): 500,
152
+ ('rdm_transfer_task', 'MINUTE'): '0',
153
+ ('rdm_transfer_task', 'HOUR'): '*/4',
154
+ ('rdm_transfer_task', 'DAY_OF_WEEK'): '*',
155
+ ('rdm_transfer_task', 'LOCK_EXPIRE_SECONDS'): 21600,
156
+ ('rdm_transfer_task', 'TIMEDELTA'): 3600,
157
+ ('rdm_transfer_task', 'ENTITIES'): '',
158
+ ('rdm_upload_status_task', 'MINUTE'): '*/30',
159
+ ('rdm_upload_status_task', 'HOUR'): '*',
160
+ ('rdm_upload_status_task', 'DAY_OF_WEEK'): '*',
161
+ ('rdm_upload_status_task', 'LOCK_EXPIRE_SECONDS'): 7200,
162
+ ('rdm_upload_data_task', 'MINUTE'): '0',
163
+ ('rdm_upload_data_task', 'HOUR'): '*/2',
164
+ ('rdm_upload_data_task', 'DAY_OF_WEEK'): '*',
165
+ ('rdm_upload_data_task', 'LOCK_EXPIRE_SECONDS'): 7200,
166
+ ('uploader_client', 'URL'): 'http://localhost:8090',
167
+ ('uploader_client', 'DATAMART_NAME'): '',
168
+ ('uploader_client', 'REQUEST_RETRIES'): 10,
169
+ ('uploader_client', 'REQUEST_TIMEOUT'): 10,
170
+ ('uploader_client', 'ENABLE_REQUEST_EMULATION'): False,
171
+ })
172
+ ```
173
+ С версии пакета 3.6 добавляются новые настройки для двух периодических задач разных очередей сбора и выгрузки данных
174
+ ```
147
175
  PROJECT_DEFAULT_CONFIG.update({
148
176
  # Настройки РВД
149
177
  ('rdm_general', 'EXPORT_ENTITY_ID_PREFIX'): '', # Дефолтное значение нужно изменить на специфическое системе
@@ -167,14 +195,18 @@ Dynamic: license-file
167
195
  ('rdm_upload_status_task', 'HOUR'): '*',
168
196
  ('rdm_upload_status_task', 'DAY_OF_WEEK'): '*',
169
197
  ('rdm_upload_status_task', 'LOCK_EXPIRE_SECONDS'): 7200,
198
+ ('rdm_upload_data_task', 'MINUTE'): '0',
199
+ ('rdm_upload_data_task', 'HOUR'): '*/2',
200
+ ('rdm_upload_data_task', 'DAY_OF_WEEK'): '*',
201
+ ('rdm_upload_data_task', 'LOCK_EXPIRE_SECONDS'): 7200,
170
202
  ('uploader_client', 'URL'): 'http://localhost:8090',
171
203
  ('uploader_client', 'DATAMART_NAME'): '',
172
204
  ('uploader_client', 'REQUEST_RETRIES'): 10,
173
205
  ('uploader_client', 'REQUEST_TIMEOUT'): 10,
174
206
  ('uploader_client', 'ENABLE_REQUEST_EMULATION'): False,
175
207
  })
176
-
177
- ```
208
+
209
+ ```
178
210
  - Получение значений настроек из конфигурационного файла в settings.py:
179
211
 
180
212
  ```
@@ -233,21 +265,48 @@ Dynamic: license-file
233
265
  RDM_UPLOADER_CLIENT_ENABLE_REQUEST_EMULATION = conf.get_bool('uploader_client', 'ENABLE_REQUEST_EMULATION')
234
266
 
235
267
  ```
236
- С версии пакета 3.6 добавляются настройки для двух новых периодических задач
237
- ```
238
- # Настройка запуска периодической задачи выгрузки данных - быстрая очередь:
239
- RDM_FAST_TRANSFER_TASK_MINUTE = conf.get('rdm_transfer_task_fast', 'MINUTE')
240
- RDM_FAST_TRANSFER_TASK_HOUR = conf.get('rdm_transfer_task_fast', 'HOUR')
241
- RDM_FAST_TRANSFER_TASK_DAY_OF_WEEK = conf.get('rdm_transfer_task_fast', 'DAY_OF_WEEK')
242
- RDM_FAST_TRANSFER_TASK_LOCK_EXPIRE_SECONDS = conf.get_int('rdm_transfer_task_fast', 'LOCK_EXPIRE_SECONDS')
243
-
244
- # Настройка запуска периодической задачи выгрузки данных - долгая очередь расчетных моделей:
245
- RDM_LONG_TRANSFER_TASK_MINUTE = conf.get('rdm_transfer_task_long', 'MINUTE')
246
- RDM_LONG_TRANSFER_TASK_HOUR = conf.get('rdm_transfer_task_long', 'HOUR')
247
- RDM_LONG_TRANSFER_TASK_DAY_OF_WEEK = conf.get('rdm_transfer_task_long', 'DAY_OF_WEEK')
248
- RDM_LONG_TRANSFER_TASK_LOCK_EXPIRE_SECONDS = conf.get_int('rdm_transfer_task_long', 'LOCK_EXPIRE_SECONDS')
249
-
250
- ```
268
+ Дополнительные настройки с версии 3.3.0
269
+ ```
270
+ # Объем очереди файлов в витрину байтах) - по умолчанию 512 Мбайт.
271
+ RDM_UPLOAD_QUEUE_MAX_SIZE = conf.get_int('rdm_general', 'UPLOAD_QUEUE_MAX_SIZE') or 500_000_000
272
+
273
+ # Настройка очереди Redis для формирования файлов РВД.
274
+ RDM_REDIS_HOST = conf.get('rdm_redis', 'REDIS_HOST')
275
+ RDM_REDIS_PORT = conf.get('rdm_redis', 'REDIS_PORT')
276
+ RDM_REDIS_DB = conf.get('rdm_redis', 'REDIS_DB')
277
+ RDM_REDIS_PASSWORD = conf.get('rdm_redis', 'REDIS_PASSWORD')
278
+
279
+ ```
280
+ Дополнительные настройки с версии 3.3.1
281
+ ```
282
+ # Таймаут для сохранения параметров в общем кеш.
283
+ RDM_REDIS_CACHE_TIMEOUT_SECONDS = conf.get_int('rdm_redis', 'REDIS_CACHE_TIMEOUT_SECONDS') or 60 * 60 * 2
284
+
285
+ ```
286
+ Дополнительные настройки с версии 3.4.2
287
+ ```
288
+ # Настройка запуска периодической задачи отправки файлов с данными РВД
289
+ RDM_UPLOAD_DATA_TASK_MINUTE = conf.get('rdm_upload_data_task', 'MINUTE')
290
+ RDM_UPLOAD_DATA_TASK_HOUR = conf.get('rdm_upload_data_task', 'HOUR')
291
+ RDM_UPLOAD_DATA_TASK_DAY_OF_WEEK = conf.get('rdm_upload_data_task', 'DAY_OF_WEEK')
292
+ RDM_UPLOAD_DATA_TASK_LOCK_EXPIRE_SECONDS = conf.get_int('rdm_upload_data_task', 'LOCK_EXPIRE_SECONDS') or 60 * 60 * 2
293
+
294
+ ```
295
+ С версии пакета 3.6 добавляются настройки для двух новых периодических задач
296
+ ```
297
+ # Настройка запуска периодической задачи выгрузки данных - быстрая очередь:
298
+ RDM_FAST_TRANSFER_TASK_MINUTE = conf.get('rdm_transfer_task_fast', 'MINUTE')
299
+ RDM_FAST_TRANSFER_TASK_HOUR = conf.get('rdm_transfer_task_fast', 'HOUR')
300
+ RDM_FAST_TRANSFER_TASK_DAY_OF_WEEK = conf.get('rdm_transfer_task_fast', 'DAY_OF_WEEK')
301
+ RDM_FAST_TRANSFER_TASK_LOCK_EXPIRE_SECONDS = conf.get_int('rdm_transfer_task_fast', 'LOCK_EXPIRE_SECONDS')
302
+
303
+ # Настройка запуска периодической задачи выгрузки данных - долгая очередь расчетных моделей:
304
+ RDM_LONG_TRANSFER_TASK_MINUTE = conf.get('rdm_transfer_task_long', 'MINUTE')
305
+ RDM_LONG_TRANSFER_TASK_HOUR = conf.get('rdm_transfer_task_long', 'HOUR')
306
+ RDM_LONG_TRANSFER_TASK_DAY_OF_WEEK = conf.get('rdm_transfer_task_long', 'DAY_OF_WEEK')
307
+ RDM_LONG_TRANSFER_TASK_LOCK_EXPIRE_SECONDS = conf.get_int('rdm_transfer_task_long', 'LOCK_EXPIRE_SECONDS')
308
+
309
+ ```
251
310
  Перечень настроек в settings.py указан в таблице ниже.
252
311
 
253
312
  | Название настройки в settings | Описание | Значение по умолчанию |
@@ -264,12 +323,37 @@ Dynamic: license-file
264
323
  | RDM_TRANSFER_TASK_MINUTE | Настройка запуска периодической задачи выгрузки данных. Минута | '0' |
265
324
  | RDM_TRANSFER_TASK_HOUR | Настройка запуска периодической задачи выгрузки данных. Час | '*/4' |
266
325
  | RDM_TRANSFER_TASK_DAY_OF_WEEK | Настройка запуска периодической задачи выгрузки данных. День недели | '*' |
267
- | RDM_TRANSFER_TASK_LOCK_EXPIRE_SECONDS | Время по истечении которого, блокировка может быть снята (в секунадх) | 21600 |
326
+ | RDM_TRANSFER_TASK_LOCK_EXPIRE_SECONDS | Время по истечении которого, блокировка может быть снята (в секундах) | 21600 |
268
327
  | RDM_UPLOAD_STATUS_TASK_MINUTE | Настройка запуска периодической задачи статуса загрузки данных в витрину. Минута | '*/30' |
269
328
  | RDM_UPLOAD_STATUS_TASK_HOUR | Настройка запуска периодической задачи статуса загрузки данных в витрину. Час | '*' |
270
329
  | RDM_UPLOAD_STATUS_TASK_DAY_OF_WEEK | Настройка запуска периодической задачи статуса загрузки данных в витрину. День недели | '*' |
271
- | RDM_UPLOAD_STATUS_TASK_LOCK_EXPIRE_SECONDS | Время по истечении которого, блокировка может быть снята (в секунадх) | 3600 |
330
+ | RDM_UPLOAD_STATUS_TASK_LOCK_EXPIRE_SECONDS | Время по истечении которого, блокировка может быть снята (в секундах) | 3600 |
272
331
  | RDM_CHECK_SUSPEND_TASK_STAGE_TIMEOUT | Дельта для определения зависшего подэтапа. Минута | 120 |
332
+
333
+ С версии пакета 3.3.0 добавляются новые настройки
334
+
335
+ | Название настройки в settings | Описание | Значение по умолчанию |
336
+ |--------------------------------------------|----------------------------------------------------------------------------------------|-----------------------|
337
+ | RDM_UPLOAD_QUEUE_MAX_SIZE | Объем очереди файлов в витрину (в байтах). | 500_000_000 |
338
+ | RDM_REDIS_HOST | Настройка очереди Redis для формирования файлов РВД (хост). | |
339
+ | RDM_REDIS_PORT | Настройка очереди Redis для формирования файлов РВД (порт). | |
340
+ | RDM_REDIS_DB | Настройка очереди Redis для формирования файлов РВД (номер бд). | |
341
+ | RDM_REDIS_PASSWORD | Настройка очереди Redis для формирования файлов РВД (пароль). | |
342
+
343
+ С версии пакета 3.3.1 добавляются новые настройки
344
+
345
+ | Название настройки в settings | Описание | Значение по умолчанию |
346
+ |--------------------------------------------|----------------------------------------------------------------------------------------|-----------------------|
347
+ | RDM_REDIS_CACHE_TIMEOUT_SECONDS | Таймаут для сохранения параметров в общем кеш (секунды). | 7200 |
348
+
349
+ С версии пакета 3.4.2 добавляются новые настройки
350
+
351
+ | Название настройки в settings | Описание | Значение по умолчанию |
352
+ |--------------------------------------------|----------------------------------------------------------------------------------------|-----------------------|
353
+ | RDM_UPLOAD_DATA_TASK_MINUTE | Настройка запуска периодической задачи отправки файлов с данными РВД (минута). | '0' |
354
+ | RDM_UPLOAD_DATA_TASK_HOUR | Настройка запуска периодической задачи отправки файлов с данными РВД (час). | '*/2' |
355
+ | RDM_UPLOAD_DATA_TASK_DAY_OF_WEEK | Настройка запуска периодической задачи отправки файлов с данными РВД (день недели). | '*' |
356
+ | RDM_UPLOAD_DATA_TASK_LOCK_EXPIRE_SECONDS | Время по истечении которого, блокировка может быть снята (в секундах). | 7200 |
273
357
 
274
358
  С версии пакета 3.6 добавляются новые настройки
275
359
 
@@ -278,11 +362,11 @@ Dynamic: license-file
278
362
  | RDM_FAST_TRANSFER_TASK_MINUTE | Настройка запуска периодической задачи (быстрая очередь) выгрузки данных. Минута | '*/5' |
279
363
  | RDM_FAST_TRANSFER_TASK_HOUR | Настройка запуска периодической задачи (быстрая очередь) выгрузки данных. Час | '*' |
280
364
  | RDM_FAST_TRANSFER_TASK_DAY_OF_WEEK | Настройка запуска периодической задачи (быстрая очередь) выгрузки данных. День недели | '*' |
281
- | RDM_FAST_TRANSFER_TASK_LOCK_EXPIRE_SECONDS | Время по истечении которого, блокировка может быть снята (в секунадх) | 1800 |
365
+ | RDM_FAST_TRANSFER_TASK_LOCK_EXPIRE_SECONDS | Время по истечении которого, блокировка может быть снята (в секундах) | 1800 |
282
366
  | RDM_LONG_TRANSFER_TASK_MINUTE | Настройка запуска периодической задачи (долгая очередь) выгрузки данных. Минута | 0 |
283
367
  | RDM_LONG_TRANSFER_TASK_HOUR | Настройка запуска периодической задачи (долгая очередь) выгрузки данных. Час | '*/6' |
284
368
  | RDM_LONG_TRANSFER_TASK_DAY_OF_WEEK | Настройка запуска периодической задачи (долгая очередь) выгрузки данных. День недели | '*' |
285
- | RDM_LONG_TRANSFER_TASK_LOCK_EXPIRE_SECONDS | Время по истечении которого, блокировка может быть снята (в секунадх) | 28800 |
369
+ | RDM_LONG_TRANSFER_TASK_LOCK_EXPIRE_SECONDS | Время по истечении которого, блокировка может быть снята (в секундах) | 28800 |
286
370
 
287
371
  - В дефолтный конфиг проекта необходимо добавить:
288
372
 
@@ -338,8 +422,38 @@ Dynamic: license-file
338
422
  # Включить эмуляцию отправки запросов
339
423
  ENABLE_REQUEST_EMULATION = True
340
424
  ```
341
- - С версии 3.6 в деволтный конфиг также нужно добавить два дополнительных раздела
342
- ```
425
+ - С версии 3.3.0 в дефолтный конфиг нужно добавить
426
+ ```
427
+ [rdm_general]
428
+ ...
429
+ # Объем очереди файлов в витрину (в байтах) - по умолчанию 512 Мбайт.
430
+ UPLOAD_QUEUE_MAX_SIZE = 500_000_000
431
+
432
+ # Настройка очереди Redis для формирования файлов РВД.
433
+ [rdm_redis]
434
+ REDIS_HOST = localhost
435
+ REDIS_PORT = 6379
436
+ REDIS_DB = 1
437
+ REDIS_PASSWORD =
438
+ ```
439
+ - С версии 3.3.1 в дефолтный конфиг нужно добавить
440
+ ```
441
+ [rdm_redis]
442
+ ...
443
+ # Таймаут для сохранения параметров в общем кеш.
444
+ REDIS_CACHE_TIMEOUT_SECONDS = 7200
445
+ ```
446
+ - С версии 3.4.2 в дефолтный конфиг нужно добавить
447
+ ```
448
+ # Настройка запуска периодической задачи отправки csv-файлов в витрину.
449
+ [rdm_upload_data_task]
450
+ MINUTE=*/2
451
+ HOUR=*
452
+ DAY_OF_WEEK=*
453
+ LOCK_EXPIRE_SECONDS = 60 * 60 * 2
454
+ ```
455
+ - С версии 3.6 в дефолтный конфиг также нужно добавить два дополнительных раздела
456
+ ```
343
457
 
344
458
  [rdm_transfer_task_fast]
345
459
  MINUTE=*/2
@@ -352,7 +466,7 @@ Dynamic: license-file
352
466
  HOUR=*
353
467
  DAY_OF_WEEK=*
354
468
  LOCK_EXPIRE_SECONDS = 21600
355
- ```
469
+ ```
356
470
  На основе дефолтного конфига произвести конфигурирование приложений.
357
471
 
358
472
  ## Сборка и распространение
@@ -6,9 +6,9 @@ edu_rdm_integration/base.py,sha256=1NgLZd0KZRRgUcVfufVIpDJU2coT2zksFGDaX4fWqps,5
6
6
  edu_rdm_integration/consts.py,sha256=QnL9TqTKuJ0MrysqtqHvtCwOFbS1T7iwcfUZGjVsZTU,1166
7
7
  edu_rdm_integration/entities.py,sha256=mhVeB88A-VD5IAzZCNeI1qnkvNoZ8LPiLBdqk1yA3Jc,14541
8
8
  edu_rdm_integration/enums.py,sha256=RpQIZM1iSgFbYDHfwrbT-BwgRf-N9ZZnJgx8UyRFQ2o,4978
9
- edu_rdm_integration/helpers.py,sha256=wr4ddI9LNsmcwdZMEUYT070YnM49ixbAQ0-tBh4gp08,14808
9
+ edu_rdm_integration/helpers.py,sha256=qwSyeIDBVEhdYG9raf3uLZPd1_2eXuNAaosSR7bLa50,14759
10
10
  edu_rdm_integration/mapping.py,sha256=1B6TsC4Os9wiM8L8BChnCNv_iWqjeWu3bdDsqKVsId0,616
11
- edu_rdm_integration/models.py,sha256=pimS5MIQzRl4b9RIUUCSxsAA54zB_aoiEY0evrywpHM,33325
11
+ edu_rdm_integration/models.py,sha256=lrlJUAJJr29rrNwNdyCkswyRGmnm8XVDQDArWVO2ivc,31907
12
12
  edu_rdm_integration/redis_cache.py,sha256=SP_rcL5t6PTVLOnEYn_NTX0Z666VdZT4By2pyED24Z4,1537
13
13
  edu_rdm_integration/signals.py,sha256=3eRlpkDcFCF6TN80-QM8yBYLcyozzcmoPjz6r4_ApWg,73
14
14
  edu_rdm_integration/storages.py,sha256=G4Q4tIyJdEyb9ka551PADCFIm66bpsJe9VBRcvQhLMI,6745
@@ -46,10 +46,11 @@ edu_rdm_integration/collect_data/helpers.py,sha256=wi1TECBFwur0LyREUwGLNXqQG731e
46
46
  edu_rdm_integration/collect_data/tests.py,sha256=_Inf8v_TS_LorBb702qykzc1Syj_tsPVRLJREcJ-XmY,5515
47
47
  edu_rdm_integration/collect_data/base/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
48
48
  edu_rdm_integration/collect_data/base/caches.py,sha256=_Ja0q3hPSE_Mq-MCZN-1jr0WvpOqUr1-CkoBf1B7qKc,2141
49
+ edu_rdm_integration/collect_data/base/consts.py,sha256=nzP7973d-YG29l-JxJcq7dF81QDLP7FRtTq0dSq46GM,304
49
50
  edu_rdm_integration/collect_data/base/functions.py,sha256=E1vYmC8F8NM5cBB5SGQEpluHrMynpjf3Ek3s0HsbxwY,2998
50
51
  edu_rdm_integration/collect_data/base/helpers.py,sha256=MsHEzkUl1KVMIxGfDkhcItXLxQNuNNOhN5tzTcPm0NQ,982
51
52
  edu_rdm_integration/collect_data/base/managers.py,sha256=hza8kugR9hbLK3LU8DBfF61ul7mPPl5pPm530QMjj0k,6143
52
- edu_rdm_integration/collect_data/base/mixins.py,sha256=kwZ77dc5dCmHVGCN6JMslpyfXfEEoks7vmXH-CzezJc,8538
53
+ edu_rdm_integration/collect_data/base/mixins.py,sha256=miAXhXdkTr6MJh_qlsGMWW4gBgcAI2gsxmmu3VFaUYw,18402
53
54
  edu_rdm_integration/collect_data/base/runners.py,sha256=Mf5Lux6IWWqKd798v149OjqfBWiDtigeFd701HSRBGg,1565
54
55
  edu_rdm_integration/collect_data/calculated/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
56
  edu_rdm_integration/collect_data/calculated/strategies.py,sha256=nppmheuzhF8H7JcfEhEZCmHI0eeRj8BbrLGNF0nsoa0,7619
@@ -168,6 +169,7 @@ edu_rdm_integration/migrations/0013_set_attachment_size.py,sha256=Gol8T137gdaCTS
168
169
  edu_rdm_integration/migrations/0014_uploaddatacommand.py,sha256=Hh0vKKiGgKOvY1kBAcmway4dSYUXwVArHAc9YrsjCIU,2079
169
170
  edu_rdm_integration/migrations/0015_set_exporting_sub_stage_status.py,sha256=zVe2baNq8JYzMPRmtpAwplmgKHOP3lwMKHLo_yRz0QE,790
170
171
  edu_rdm_integration/migrations/0016_transferredentity_queue_level.py,sha256=xMnDYE5_fK8Sdwq-1GwJlJZlVoz4e4yml0SDueKcbUA,587
172
+ edu_rdm_integration/migrations/0017_delete_uploaddatacommand.py,sha256=S-sUKDGC6PhcXybZ84ZFXPjB_Dnw4TMVzlZH5Lb_DdU,330
171
173
  edu_rdm_integration/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
172
174
  edu_rdm_integration/registry/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
173
175
  edu_rdm_integration/registry/actions.py,sha256=-CHe95jbxO9JAEaOx6nV6Avn75ynppvZRWN8YPc6c6s,6074
@@ -180,8 +182,8 @@ edu_rdm_integration/uploader_log/enums.py,sha256=rgSO3BL2rh2xpfm0Pt4waQW8fB1VMJL
180
182
  edu_rdm_integration/uploader_log/managers.py,sha256=OFdToWV8qhdfeGNpd-UWAmSEISzixmVQ6LF75EW7gzA,3248
181
183
  edu_rdm_integration/uploader_log/ui.py,sha256=YM9Buqp2wxE95Wf5gvAATBzuYzDOossK1sEmvFk07cI,2110
182
184
  edu_rdm_integration/uploader_log/templates/ui-js/object-grid-buttons.js,sha256=2xyGe0wdVokM0RhpzRzcRvJPBkBmPe3SlZry4oP4Nzs,6201
183
- edu_rdm_integration-3.6.0.dist-info/licenses/LICENSE,sha256=uw43Gjjj-1vXWCItfSrNDpbejnOwZMrNerUh8oWbq8Q,3458
184
- edu_rdm_integration-3.6.0.dist-info/METADATA,sha256=rV5ZHyItlhOmIl5k0jC3nfJTrv6k7Cmr_S-bXUsI480,27415
185
- edu_rdm_integration-3.6.0.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
186
- edu_rdm_integration-3.6.0.dist-info/top_level.txt,sha256=nRJV0O14UtNE-jGIYG03sohgFnZClvf57H5m6VBXe9Y,20
187
- edu_rdm_integration-3.6.0.dist-info/RECORD,,
185
+ edu_rdm_integration-3.8.0.dist-info/licenses/LICENSE,sha256=uw43Gjjj-1vXWCItfSrNDpbejnOwZMrNerUh8oWbq8Q,3458
186
+ edu_rdm_integration-3.8.0.dist-info/METADATA,sha256=RG6vIjFCjWp4m7xz-Eey7SLDFCFRIhi3AX6D24dHRcQ,35263
187
+ edu_rdm_integration-3.8.0.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
188
+ edu_rdm_integration-3.8.0.dist-info/top_level.txt,sha256=nRJV0O14UtNE-jGIYG03sohgFnZClvf57H5m6VBXe9Y,20
189
+ edu_rdm_integration-3.8.0.dist-info/RECORD,,