polyapi 5.9.17__tar.gz → 5.9.18__tar.gz
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.
- {polyapi-5.9.17 → polyapi-5.9.18}/PKG-INFO +1 -1
- {polyapi-5.9.17 → polyapi-5.9.18}/polyapi.egg-info/PKG-INFO +1 -1
- {polyapi-5.9.17 → polyapi-5.9.18}/polyapi.egg-info/SOURCES.txt +0 -3
- {polyapi-5.9.17 → polyapi-5.9.18}/polyapi.egg-info/top_level.txt +0 -1
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/business_scenarios.py +280 -79
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/common/consts.py +3 -1
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/common/params_models.py +9 -7
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/error_handler.py +128 -31
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/helper.py +95 -5
- {polyapi-5.9.17 → polyapi-5.9.18}/pyproject.toml +1 -1
- {polyapi-5.9.17 → polyapi-5.9.18}/setup.py +2 -2
- polyapi-5.9.17/tests/__init__.py +0 -1
- polyapi-5.9.17/tests/conftest.py +0 -65
- polyapi-5.9.17/tests/const.py +0 -312
- {polyapi-5.9.17 → polyapi-5.9.18}/LICENSE.txt +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/README.md +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polyapi.egg-info/dependency_links.txt +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polyapi.egg-info/requires.txt +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/__init__.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/authorization.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/business_logic_doc.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/commands/__init__.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/commands/base_command.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/commands/olap_module.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/commands/other_modules.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/common/__init__.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/common/helper_funcs.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/exceptions.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/executor.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/graph/__init__.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/graph/base_graph.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/graph/graph_interface.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/graph/types/__init__.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/graph/types/areas.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/graph/types/balls.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/graph/types/chord.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/graph/types/circles.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/graph/types/circles_series.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/graph/types/corridors.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/graph/types/cumulative_areas.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/graph/types/cumulative_cylinders.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/graph/types/cylinders.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/graph/types/graph.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/graph/types/lines.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/graph/types/pies.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/graph/types/point.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/graph/types/point_series.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/graph/types/pools.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/graph/types/pools_3d.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/graph/types/radar.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/graph/types/sankey.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/polymatica/graph/types/surface.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/setup.cfg +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/tests/test_create_sphere.py +0 -0
- {polyapi-5.9.17 → polyapi-5.9.18}/tests/test_update_cube.py +0 -0
|
@@ -47,8 +47,5 @@ polymatica/graph/types/pools_3d.py
|
|
|
47
47
|
polymatica/graph/types/radar.py
|
|
48
48
|
polymatica/graph/types/sankey.py
|
|
49
49
|
polymatica/graph/types/surface.py
|
|
50
|
-
tests/__init__.py
|
|
51
|
-
tests/conftest.py
|
|
52
|
-
tests/const.py
|
|
53
50
|
tests/test_create_sphere.py
|
|
54
51
|
tests/test_update_cube.py
|
|
@@ -37,6 +37,7 @@ from polymatica.common import (
|
|
|
37
37
|
LOGIC_FUNCS,
|
|
38
38
|
MEASURE_INT_STR_TYPES_MAP,
|
|
39
39
|
MIN_MEASURE_CELL_WIDTH,
|
|
40
|
+
MIN_OLAP_HEIGHT,
|
|
40
41
|
MIN_OLAP_WIDTH,
|
|
41
42
|
MULTISPHERE_ID,
|
|
42
43
|
OPERANDS,
|
|
@@ -3825,24 +3826,33 @@ class BusinessLogic:
|
|
|
3825
3826
|
|
|
3826
3827
|
@timing
|
|
3827
3828
|
def set_width_columns(
|
|
3828
|
-
self, measures: List, left_dims: List, width: int = 890, height: int = 540
|
|
3829
|
+
self, measures: List[int], left_dims: List[int], width: int = 890, height: int = 540
|
|
3829
3830
|
) -> dict:
|
|
3830
3831
|
"""
|
|
3831
|
-
Установить ширину колонок в текущем (активном) модуле.
|
|
3832
|
-
|
|
3833
|
-
:param measures: (List) список новых значений ширины
|
|
3834
|
-
|
|
3832
|
+
Установить ширину колонок левых размерностей и фактов в текущем (активном) модуле.
|
|
3833
|
+
Установить ширину окна мультисферы.
|
|
3834
|
+
:param measures: (List[int]) список новых значений ширины фактов в формате int.
|
|
3835
|
+
Длина списка должна совпадать с количеством видимых фактов в мультисфере без учёта верхних
|
|
3835
3836
|
размерностей. То есть:
|
|
3836
3837
|
1. Если в мультисфере нет вынесенных вверх размерностей, то длина списка должна совпадать с
|
|
3837
|
-
количеством
|
|
3838
|
+
количеством видимых фактов в мультисфере.
|
|
3838
3839
|
2. Если в мультисфере есть вынесенные вверх размерности, то длина списка должна совпадать с
|
|
3839
|
-
количеством уникальных (не дублирующихся из-за верхних размерностей)
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
:param
|
|
3843
|
-
|
|
3840
|
+
количеством уникальных (не дублирующихся из-за верхних размерностей) видимых фактов в мультисфере.
|
|
3841
|
+
Минимально допустимое значение ширины для каждого факта - 60, если будет задано меньшее значение,
|
|
3842
|
+
то будет передано 60.
|
|
3843
|
+
:param left_dims: (List[int]) список новых значений ширины вынесенных влево размерностей в формате int.
|
|
3844
|
+
Длина списка должна совпадать с количеством вынесенных влево размерностей мультисферы!
|
|
3845
|
+
Минимально допустимое значение ширины для каждой вынесенной влево размерности - 110,
|
|
3846
|
+
если будет задано меньшее значение, то будет передано 110.
|
|
3847
|
+
:param width: (int) ширина окна мультисферы. Необязательный параметр, по умолчанию - 890,
|
|
3848
|
+
минимальное значение - 640.
|
|
3849
|
+
:param height: (int) высота окна мультисферы. Необязательный параметр, по умолчанию - 540,
|
|
3850
|
+
минимальное значение - 440.
|
|
3851
|
+
:call_example:
|
|
3852
|
+
session.set_width_columns(measures=[100, 150, 120], left_dims=[120, 120], width=700, height=600)
|
|
3844
3853
|
:return: Команда ("user_iface", "save_settings").
|
|
3845
3854
|
"""
|
|
3855
|
+
# TODO: убрать num_row=20, num_col=20, загружать чанками
|
|
3846
3856
|
result = self.execute_olap_command(
|
|
3847
3857
|
command_name="view",
|
|
3848
3858
|
state="get",
|
|
@@ -3865,16 +3875,27 @@ class BusinessLogic:
|
|
|
3865
3875
|
|
|
3866
3876
|
# проверки
|
|
3867
3877
|
try:
|
|
3868
|
-
self.checks(
|
|
3869
|
-
self.func_name, measures, measures_ids, left_dims, left_dims_data
|
|
3878
|
+
measures, left_dims = self.checks(
|
|
3879
|
+
self.func_name, measures, measures_ids, left_dims, left_dims_data, width, height
|
|
3870
3880
|
)
|
|
3871
3881
|
except Exception as e:
|
|
3872
3882
|
return self._raise_exception(
|
|
3873
3883
|
PolymaticaException, str(e), with_traceback=False
|
|
3874
3884
|
)
|
|
3875
3885
|
|
|
3886
|
+
# ограничиваем ширину окна мультисферы минимально допустимой
|
|
3887
|
+
width = max(width, MIN_OLAP_WIDTH)
|
|
3888
|
+
height = max(height, MIN_OLAP_HEIGHT)
|
|
3889
|
+
|
|
3890
|
+
# извлекаем текущее имя модуля
|
|
3891
|
+
current_settings = self.execute_manager_command(
|
|
3892
|
+
command_name="user_iface", state="load_settings", module_id=self.multisphere_module_id
|
|
3893
|
+
)
|
|
3894
|
+
title = self.h.parse_result(result=current_settings, key="settings", nested_key="title")
|
|
3895
|
+
|
|
3876
3896
|
# сохраняем новые настройки
|
|
3877
3897
|
settings = {
|
|
3898
|
+
"title": title,
|
|
3878
3899
|
"dimAndFactShow": True,
|
|
3879
3900
|
"itemWidth": measures,
|
|
3880
3901
|
"geometry": {"width": width, "height": height},
|
|
@@ -4045,15 +4066,17 @@ class BusinessLogic:
|
|
|
4045
4066
|
sql_params: dict = None,
|
|
4046
4067
|
user_interval: str = "с текущего дня",
|
|
4047
4068
|
filepath: str = "",
|
|
4048
|
-
separator: str = "",
|
|
4069
|
+
separator: str = ",",
|
|
4049
4070
|
increment_dim: str = "",
|
|
4050
4071
|
interval_dim: str = "",
|
|
4051
4072
|
interval_borders: list = None,
|
|
4052
|
-
encoding: str = "",
|
|
4073
|
+
encoding: str = "UTF-8",
|
|
4053
4074
|
delayed: bool = False,
|
|
4054
4075
|
modified_records_params: dict = None,
|
|
4055
4076
|
relevance_date: dict = None,
|
|
4056
4077
|
indirect_cpu_load_parameter: dict = None,
|
|
4078
|
+
measures: dict = None,
|
|
4079
|
+
sources: list = None,
|
|
4057
4080
|
) -> dict:
|
|
4058
4081
|
"""
|
|
4059
4082
|
Создать новую мультисферу (куб).
|
|
@@ -4063,8 +4086,8 @@ class BusinessLogic:
|
|
|
4063
4086
|
начиная с единицы, например "cube(1)", "cube(2)".
|
|
4064
4087
|
:param source_name: (str) название источника данных, оно должно содержать от 5 до 100 символов, допустимы
|
|
4065
4088
|
русские и английские буквы, цифры, пробел, '_' , '-').
|
|
4066
|
-
:param file_type: (str) тип источника
|
|
4067
|
-
|
|
4089
|
+
:param file_type: (str) тип источника данных. Допустимые типы источников данных:
|
|
4090
|
+
"excel", "csv", "mssql", "mysql", "psql", "jdbc", "odbc".
|
|
4068
4091
|
:param update_params: (dict) параметры обновления мультисферы. Не используется для мультисфер,
|
|
4069
4092
|
созданных из файловых источников ("excel", "csv").
|
|
4070
4093
|
Имеет структуру:
|
|
@@ -4135,7 +4158,9 @@ class BusinessLogic:
|
|
|
4135
4158
|
"с предыдущего года", "с указанной даты", "с и по указанную дату"];
|
|
4136
4159
|
актуально только для интервального обновления.
|
|
4137
4160
|
:param filepath: (str) путь к файлу, либо название файла, если он лежит в той же директории.
|
|
4138
|
-
:param separator: (str) разделитель столбцов; обязателен для csv-источника.
|
|
4161
|
+
:param separator: (str) разделитель столбцов; обязателен для csv-источника. По умолчанию запятая - ",".
|
|
4162
|
+
Если значение separator не совпадает с разделителем в источнике, возможна ошибка "Error in response: Facts
|
|
4163
|
+
list is empty". В этом случае необходимо поменять значение separator.
|
|
4139
4164
|
:param increment_dim: (str) название размерности для инкрементального обновления; размерность должна иметь
|
|
4140
4165
|
один из следующих типов: uint8, uint16, uint32, uint64, double, date, time, datetime.
|
|
4141
4166
|
:param interval_dim: (str) название размерности для интервального обновления; размерность должна иметь
|
|
@@ -4145,7 +4170,7 @@ class BusinessLogic:
|
|
|
4145
4170
|
в список только одно значение времени, а для обновления "с и по указанную дату" - два значения времени,
|
|
4146
4171
|
при этом второе значение должно быть больше первого. Формат значений времени: "DD.MM.YYYY". Все остальные
|
|
4147
4172
|
значения, если они будут переданы, будут игнорироваться. Актуально только для интервального обновления.
|
|
4148
|
-
:param encoding: (str)
|
|
4173
|
+
:param encoding: (str) кодировка; обязательна для csv-источника. По умолчанию - "UTF-8".
|
|
4149
4174
|
:param delayed: (bool) параметр, определяющий, будет ли отложено создание мультисферы.
|
|
4150
4175
|
Если False, то не будет, и мультисфера будет автоматически создана.
|
|
4151
4176
|
Если True: если настроено расписание обновлений (schedule в update_params),
|
|
@@ -4206,6 +4231,36 @@ class BusinessLogic:
|
|
|
4206
4231
|
"use_default_value": False,
|
|
4207
4232
|
"percent": 70,
|
|
4208
4233
|
}
|
|
4234
|
+
:param measures: (dict) словарь, в который передаются факты, которые требуется удалить из создаваемой
|
|
4235
|
+
мультисферы, либо факты, которые требуется добавить в создаваемую мультисферу, исключив все остальные,
|
|
4236
|
+
а также список фактов, которые требуется добавить в создаваемую мультисферу с определенными настройками.
|
|
4237
|
+
Необязательный аргумент.
|
|
4238
|
+
Поля, передаваемые в словарь measures:
|
|
4239
|
+
"measures_list_mode": (str) - Режим работы списка фактов measures_list.
|
|
4240
|
+
Допустимые значения: "blacklist", "whitelist". Значение по умолчанию — "whitelist".
|
|
4241
|
+
"measures_list": (List[str]) - Если measures_list_mode = "blacklist", то measures_list — это
|
|
4242
|
+
список наименований полей источника, которые требуется удалить из списка фактов создаваемой
|
|
4243
|
+
мультисферы.
|
|
4244
|
+
Если measures_list_mode = "whitelist", то measures_list — это список наименований полей источника,
|
|
4245
|
+
которые требуется добавить в список фактов создаваемой мультисферы, исключив при этом
|
|
4246
|
+
все остальные.
|
|
4247
|
+
Необязательный аргумент. Если не заполнен, мультисфера создается со списком фактов по умолчанию.
|
|
4248
|
+
"measures_custom_list": (List[dict]) - Список словарей, каждый из которых содержит информацию
|
|
4249
|
+
по одному факту, который требуется добавить в мультисферу с настройками, отличными от настроек
|
|
4250
|
+
по умолчанию.
|
|
4251
|
+
Необязательный аргумент. Если не заполнен, мультисфера создается с настройками фактов по умолчанию.
|
|
4252
|
+
Поля, передаваемые в словарь measures_custom_list:
|
|
4253
|
+
"source_column": (str) - Название колонки источника. Допустимо передавать несколько словарей
|
|
4254
|
+
с одинаковым значением source_column и разным значением measure_name — будет создано
|
|
4255
|
+
несколько фактов с разными названиями на основе одной колонки источника.
|
|
4256
|
+
"measure_name": (str) - Имя факта. Если значение не заполнено, имя факта совпадает с
|
|
4257
|
+
названием колонки источника.
|
|
4258
|
+
"nullable": (bool) - Параметр, определяющий допустимость пропусков. Если True — пропуски
|
|
4259
|
+
допустимы, если False — пропуски заменяются нулями. Значение по умолчанию — False.
|
|
4260
|
+
:param sources: (list) Параметр, содержащий несколько источников данных.
|
|
4261
|
+
Задается в методе create_sphere_multisource, в текущем методе create_sphere не применим.
|
|
4262
|
+
Метод create_sphere поддерживает только один источник данных через параметры
|
|
4263
|
+
source_name, file_type, sql_params, filepath, separator, encoding.
|
|
4209
4264
|
|
|
4210
4265
|
:return: (dict) Результат команды ("user_cube", "save_ext_info_several_sources_request").
|
|
4211
4266
|
"""
|
|
@@ -4239,7 +4294,7 @@ class BusinessLogic:
|
|
|
4239
4294
|
modified_records_params["version"] = 1
|
|
4240
4295
|
elif algo_version not in (0, 1):
|
|
4241
4296
|
self.logger.warning(f"Param 'modified_records_algo_version' must be 0 or 1, "
|
|
4242
|
-
|
|
4297
|
+
f"not {algo_version}. Changed to 1")
|
|
4243
4298
|
modified_records_params["version"] = 1
|
|
4244
4299
|
|
|
4245
4300
|
# проверки
|
|
@@ -4262,6 +4317,8 @@ class BusinessLogic:
|
|
|
4262
4317
|
modified_records_params=modified_records_params,
|
|
4263
4318
|
relevance_date=relevance_date,
|
|
4264
4319
|
indirect_cpu_load_parameter=indirect_cpu_load_parameter,
|
|
4320
|
+
measures=measures,
|
|
4321
|
+
sources=sources,
|
|
4265
4322
|
)
|
|
4266
4323
|
(
|
|
4267
4324
|
cube_name,
|
|
@@ -4280,6 +4337,8 @@ class BusinessLogic:
|
|
|
4280
4337
|
modified_records_params,
|
|
4281
4338
|
relevance_date,
|
|
4282
4339
|
indirect_cpu_load_parameter,
|
|
4340
|
+
measures,
|
|
4341
|
+
sources,
|
|
4283
4342
|
) = (
|
|
4284
4343
|
params.cube_name,
|
|
4285
4344
|
params.source_name,
|
|
@@ -4297,6 +4356,8 @@ class BusinessLogic:
|
|
|
4297
4356
|
params.modified_records_params,
|
|
4298
4357
|
params.relevance_date,
|
|
4299
4358
|
params.indirect_cpu_load_parameter,
|
|
4359
|
+
params.measures,
|
|
4360
|
+
params.sources,
|
|
4300
4361
|
)
|
|
4301
4362
|
|
|
4302
4363
|
try:
|
|
@@ -4315,6 +4376,8 @@ class BusinessLogic:
|
|
|
4315
4376
|
encoding,
|
|
4316
4377
|
relevance_date,
|
|
4317
4378
|
indirect_cpu_load_parameter,
|
|
4379
|
+
measures,
|
|
4380
|
+
sources,
|
|
4318
4381
|
)
|
|
4319
4382
|
except Exception as e:
|
|
4320
4383
|
return self._raise_exception(ValueError, str(e), with_traceback=False)
|
|
@@ -4330,65 +4393,91 @@ class BusinessLogic:
|
|
|
4330
4393
|
self._convert_schedule_item(time_zones, schedule_item)
|
|
4331
4394
|
schedule_items = [item for item in schedule_items_tmp if item]
|
|
4332
4395
|
|
|
4333
|
-
# параметр source_type для различных форматов данных
|
|
4334
|
-
source_type = self.h.get_source_type(file_type)
|
|
4335
|
-
|
|
4336
4396
|
# создать мультисферу, получить id куба
|
|
4337
4397
|
res = self.execute_manager_command(
|
|
4338
4398
|
command_name="user_cube", state="create_cube_request", cube_name=cube_name
|
|
4339
4399
|
)
|
|
4340
4400
|
self.cube_id = self.h.parse_result(result=res, key="cube_id")
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
|
|
4355
|
-
|
|
4356
|
-
|
|
4357
|
-
|
|
4358
|
-
|
|
4359
|
-
|
|
4360
|
-
|
|
4361
|
-
|
|
4362
|
-
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4367
|
-
|
|
4368
|
-
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
|
|
4372
|
-
|
|
4373
|
-
|
|
4374
|
-
|
|
4375
|
-
|
|
4376
|
-
|
|
4377
|
-
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
|
|
4401
|
+
|
|
4402
|
+
if sources:
|
|
4403
|
+
# режим нескольких источников (создание через create_sphere_multisource)
|
|
4404
|
+
all_sources = sources
|
|
4405
|
+
else:
|
|
4406
|
+
# режим одного источника - создаем источник из параметров метода
|
|
4407
|
+
all_sources = [{
|
|
4408
|
+
"source_name": source_name,
|
|
4409
|
+
"file_type": file_type,
|
|
4410
|
+
"sql_params": sql_params or {},
|
|
4411
|
+
"filepath": filepath,
|
|
4412
|
+
"separator": separator,
|
|
4413
|
+
"encoding": encoding,
|
|
4414
|
+
}]
|
|
4415
|
+
|
|
4416
|
+
# обрабатываем каждый источник
|
|
4417
|
+
datasources = []
|
|
4418
|
+
for source in all_sources:
|
|
4419
|
+
source_name = source.get("source_name")
|
|
4420
|
+
file_type = source.get("file_type")
|
|
4421
|
+
sql_params = source.get("sql_params", {})
|
|
4422
|
+
filepath = source.get("filepath", "")
|
|
4423
|
+
separator = source.get("separator", ",")
|
|
4424
|
+
encoding = source.get("encoding", "UTF-8")
|
|
4425
|
+
|
|
4426
|
+
# параметр source_type для различных форматов данных
|
|
4427
|
+
source_type = self.h.get_source_type(file_type)
|
|
4428
|
+
|
|
4429
|
+
# загрузка csv/excel файла
|
|
4430
|
+
encoded_file_name = ""
|
|
4431
|
+
if (file_type == "excel") or (file_type == "csv"):
|
|
4432
|
+
encoded_file_name = self.h.upload_file_to_server(filepath)
|
|
4433
|
+
|
|
4434
|
+
# превью-данные
|
|
4435
|
+
preview_data = {
|
|
4436
|
+
"name": source_name,
|
|
4437
|
+
"server": "",
|
|
4438
|
+
"server_type": source_type,
|
|
4439
|
+
"login": "",
|
|
4440
|
+
"passwd": "",
|
|
4441
|
+
"database": "",
|
|
4442
|
+
"sql_query": separator,
|
|
4443
|
+
"skip": -1,
|
|
4444
|
+
}
|
|
4445
|
+
|
|
4446
|
+
# для бд выставить параметры server, login, passwd и sql_query
|
|
4447
|
+
if (file_type != "csv") and (file_type != "excel"):
|
|
4448
|
+
preview_data.update(sql_params)
|
|
4449
|
+
|
|
4450
|
+
# для формата данных csv выставить кодировку
|
|
4451
|
+
if file_type == "csv":
|
|
4452
|
+
preview_data.update({"encoding": encoding, "server": encoded_file_name})
|
|
4453
|
+
|
|
4454
|
+
# для формата данных excel указать параметр server
|
|
4455
|
+
if file_type == "excel":
|
|
4456
|
+
preview_data.update({"server": encoded_file_name})
|
|
4457
|
+
|
|
4458
|
+
# соединиться с бд в тестовом режиме, проверить соединение
|
|
4459
|
+
conn_result = self.execute_manager_command(
|
|
4460
|
+
command_name="user_cube",
|
|
4461
|
+
state="test_source_connection_request",
|
|
4462
|
+
datasource=preview_data,
|
|
4463
|
+
)
|
|
4464
|
+
conn_status = self.h.parse_result(conn_result, "status")
|
|
4465
|
+
if conn_status.get("code") != 0:
|
|
4466
|
+
error_msg = "Unable to connect to database: {}".format(
|
|
4467
|
+
conn_status.get("message", "description not found!")
|
|
4468
|
+
)
|
|
4469
|
+
return self._raise_exception(
|
|
4470
|
+
DBConnectionError, error_msg, with_traceback=False
|
|
4471
|
+
)
|
|
4472
|
+
|
|
4473
|
+
datasources.append(preview_data)
|
|
4385
4474
|
|
|
4386
4475
|
# из структуры данных получаем словари с данными о размерностях и фактах
|
|
4387
4476
|
self.execute_manager_command(
|
|
4388
4477
|
command_name="user_cube",
|
|
4389
4478
|
state="get_fields_request",
|
|
4390
4479
|
cube_id=self.cube_id,
|
|
4391
|
-
datasources=
|
|
4480
|
+
datasources=datasources,
|
|
4392
4481
|
)
|
|
4393
4482
|
result = self.execute_manager_command(
|
|
4394
4483
|
command_name="user_cube",
|
|
@@ -4398,8 +4487,16 @@ class BusinessLogic:
|
|
|
4398
4487
|
)
|
|
4399
4488
|
|
|
4400
4489
|
try:
|
|
4490
|
+
# определяем file_type для обработки
|
|
4491
|
+
effective_file_type = "csv" if sources and any(s.get("file_type") == "csv" for s in sources) \
|
|
4492
|
+
else (file_type if not sources else None)
|
|
4493
|
+
|
|
4401
4494
|
# получаем и обрабатываем информацию о фактах и размерностях куба
|
|
4402
|
-
|
|
4495
|
+
processed_dims, processed_measures = self.h.get_and_process_dims_and_measures(
|
|
4496
|
+
result,
|
|
4497
|
+
effective_file_type,
|
|
4498
|
+
measures,
|
|
4499
|
+
)
|
|
4403
4500
|
except Exception as e:
|
|
4404
4501
|
return self._raise_exception(
|
|
4405
4502
|
PolymaticaException, str(e), with_traceback=False
|
|
@@ -4409,8 +4506,8 @@ class BusinessLogic:
|
|
|
4409
4506
|
command_params = {
|
|
4410
4507
|
"cube_id": self.cube_id,
|
|
4411
4508
|
"cube_name": cube_name,
|
|
4412
|
-
"dims":
|
|
4413
|
-
"facts":
|
|
4509
|
+
"dims": processed_dims,
|
|
4510
|
+
"facts": processed_measures,
|
|
4414
4511
|
"schedule": {"delayed": delayed, "items": schedule_items},
|
|
4415
4512
|
}
|
|
4416
4513
|
if update_type == "ручное":
|
|
@@ -4420,7 +4517,7 @@ class BusinessLogic:
|
|
|
4420
4517
|
elif update_type == "инкрементальное":
|
|
4421
4518
|
# получаем идентификатор размерности инкремента
|
|
4422
4519
|
increment_dim_id = ""
|
|
4423
|
-
for dim in
|
|
4520
|
+
for dim in processed_dims:
|
|
4424
4521
|
if dim.get("name") == increment_dim:
|
|
4425
4522
|
current_type = POLYMATICA_INT_TYPES_MAP.get(dim.get("type"))
|
|
4426
4523
|
if current_type not in (
|
|
@@ -4452,7 +4549,7 @@ class BusinessLogic:
|
|
|
4452
4549
|
elif update_type == "интервальное":
|
|
4453
4550
|
# получаем идентификатор размерности
|
|
4454
4551
|
interval_dim_id = ""
|
|
4455
|
-
for dim in
|
|
4552
|
+
for dim in processed_dims:
|
|
4456
4553
|
if dim.get("name") == interval_dim:
|
|
4457
4554
|
current_type = POLYMATICA_INT_TYPES_MAP.get(dim.get("type"))
|
|
4458
4555
|
if current_type not in ("date", "datetime"):
|
|
@@ -4497,7 +4594,7 @@ class BusinessLogic:
|
|
|
4497
4594
|
modified_records_algo_version = modified_records_params.get("version")
|
|
4498
4595
|
modified_records_key_id = ""
|
|
4499
4596
|
modified_records_date_id = ""
|
|
4500
|
-
for dim in
|
|
4597
|
+
for dim in processed_dims:
|
|
4501
4598
|
if dim.get("name") == modified_records_key:
|
|
4502
4599
|
modified_records_key_id = dim.get("id")
|
|
4503
4600
|
if dim.get("name") == modified_records_date:
|
|
@@ -4535,7 +4632,7 @@ class BusinessLogic:
|
|
|
4535
4632
|
)
|
|
4536
4633
|
|
|
4537
4634
|
# обрабатываем и добавляем параметры даты актуальности данных
|
|
4538
|
-
relevance_date_dict = self._process_relevance_date(relevance_date,
|
|
4635
|
+
relevance_date_dict = self._process_relevance_date(relevance_date, processed_dims)
|
|
4539
4636
|
|
|
4540
4637
|
command_params.update({"relevance_date": relevance_date_dict})
|
|
4541
4638
|
|
|
@@ -4551,6 +4648,108 @@ class BusinessLogic:
|
|
|
4551
4648
|
**command_params,
|
|
4552
4649
|
)
|
|
4553
4650
|
|
|
4651
|
+
@timing
|
|
4652
|
+
def create_sphere_multisource(
|
|
4653
|
+
self,
|
|
4654
|
+
cube_name: str,
|
|
4655
|
+
sources: list,
|
|
4656
|
+
update_params: dict = None,
|
|
4657
|
+
user_interval: str = "с текущего дня",
|
|
4658
|
+
increment_dim: str = "",
|
|
4659
|
+
interval_dim: str = "",
|
|
4660
|
+
interval_borders: list = None,
|
|
4661
|
+
delayed: bool = False,
|
|
4662
|
+
modified_records_params: dict = None,
|
|
4663
|
+
relevance_date: dict = None,
|
|
4664
|
+
indirect_cpu_load_parameter: dict = None,
|
|
4665
|
+
measures: dict = None,
|
|
4666
|
+
) -> dict:
|
|
4667
|
+
"""
|
|
4668
|
+
Создать новую мультисферу (куб) из нескольких источников.
|
|
4669
|
+
Описание остальных параметров см. в методе create_sphere.
|
|
4670
|
+
|
|
4671
|
+
:param cube_name: (str) название создаваемой мультисферы (куба), оно должно состоять из 5 и более символов,
|
|
4672
|
+
допустимы буквы, цифры, специальные символы (кроме: % ^ & = ; ± § ` ~ ] [ } { < >).
|
|
4673
|
+
Если мультисфера с таким названием присутствует на сервере, то к названию будет добавлено число в скобках,
|
|
4674
|
+
начиная с единицы, например "cube(1)", "cube(2)".
|
|
4675
|
+
:param sources: (list) Источники. Представляет собой список, элементами которого являются
|
|
4676
|
+
однотипные словари, описывающие источники.
|
|
4677
|
+
|
|
4678
|
+
Словарь, описывающий источник (из списка sources), должен содержать следующие поля:
|
|
4679
|
+
- source_name: (str) название источника данных, оно должно содержать от 5 до 100 символов, допустимы
|
|
4680
|
+
русские и английские буквы, цифры, пробел, '_' , '-').
|
|
4681
|
+
- file_type: (str) тип источника данных. Допустимые типы источников данных:
|
|
4682
|
+
Примеры основных источников данных: "excel", "csv", "mssql", "mysql", "psql", "jdbc", "odbc".
|
|
4683
|
+
- sql_params: (dict) параметры для источника данных SQL.
|
|
4684
|
+
Поля, передаваемые в словарь:
|
|
4685
|
+
"server" - хост, который может быть задан в виде IP-адреса сервера (например, "10.18.0.132"),
|
|
4686
|
+
либо в виде имени сервера (например, "polymatica.database1.ru");
|
|
4687
|
+
опционально также может быть задан порт подключения, в таком случае он должен идти после указания
|
|
4688
|
+
хоста через двоеточие (например, "10.18.0.132:5433", "polymatica.database1.ru:5433");
|
|
4689
|
+
в случае, если порт явно не указан, подразумевается порт по-умолчанию 5432.
|
|
4690
|
+
Для источника данных JDBC в этом поле необходимо указать DSN в формате,
|
|
4691
|
+
например, jdbc:mysql://192.111.11.11:3306/database. Если database стандартный, то возможно
|
|
4692
|
+
подключение и без указания его в DSN.
|
|
4693
|
+
"login" - логин пользователя.
|
|
4694
|
+
"passwd" - пароль пользователя.
|
|
4695
|
+
"database" - имя базы данных. Для источника данных JDBC указывать "database" не надо, оно указывается
|
|
4696
|
+
после хоста в строке DSN (см. описание поля "server")
|
|
4697
|
+
"sql_query" - запрос, который необходимо выполнить на сервере.
|
|
4698
|
+
Пример задания параметра:
|
|
4699
|
+
{
|
|
4700
|
+
"server": "10.8.0.115:5433",
|
|
4701
|
+
"login": "your_user",
|
|
4702
|
+
"passwd": "your_password",
|
|
4703
|
+
"database": "database_name",
|
|
4704
|
+
"sql_query": "SELECT * FROM table"
|
|
4705
|
+
}
|
|
4706
|
+
- filepath: (str) путь к файлу, либо название файла, если он лежит в той же директории.
|
|
4707
|
+
- separator: (str) разделитель столбцов; обязателен для csv-источника, по умолчанию ",". Если значение
|
|
4708
|
+
separator не совпадает с разделителем в источнике, возможна ошибка "Error in response: Facts list
|
|
4709
|
+
is empty". В этом случае необходимо поменять значение separator.
|
|
4710
|
+
- encoding: (str) кодировка, например UTF-8; обязательна для csv-источника, по умолчанию "UTF-8".
|
|
4711
|
+
|
|
4712
|
+
:param update_params: (dict) параметры обновления мультисферы. См. описание в create_sphere.
|
|
4713
|
+
:param user_interval: (str) интервал обновлений. См. описание в create_sphere.
|
|
4714
|
+
:param increment_dim: (str) название размерности для инкрементального обновления. См. описание в create_sphere.
|
|
4715
|
+
:param interval_dim: (str) название размерности для интервального обновления. См. описание в create_sphere.
|
|
4716
|
+
:param interval_borders: (list) временные границы для интервалов обновлений. См. описание в create_sphere.
|
|
4717
|
+
:param delayed: (bool) параметр, определяющий, будет ли отложено создание мультисферы.
|
|
4718
|
+
См. описание в create_sphere.
|
|
4719
|
+
:param modified_records_params: (dict) параметры обновления для типа "обновление измененных записей".
|
|
4720
|
+
См. описание в create_sphere.
|
|
4721
|
+
:param relevance_date: (dict) словарь, содержащий параметры отображения даты актуальности данных.
|
|
4722
|
+
См. описание в create_sphere.
|
|
4723
|
+
:param indirect_cpu_load_parameter: (dict) словарь, содержащий параметры предельного процента использования CPU.
|
|
4724
|
+
См. описание в create_sphere.
|
|
4725
|
+
:param measures: (dict) словарь, в который передаются факты. См. описание в create_sphere.
|
|
4726
|
+
|
|
4727
|
+
:return: (dict) Результат команды ("user_cube", "save_ext_info_several_sources_request").
|
|
4728
|
+
"""
|
|
4729
|
+
if len(sources) <= 1:
|
|
4730
|
+
return self._raise_exception(ValueError, "For one source use create_sphere method", with_traceback=False)
|
|
4731
|
+
|
|
4732
|
+
return self.create_sphere(
|
|
4733
|
+
cube_name=cube_name,
|
|
4734
|
+
source_name=None, # не используется в режиме нескольких источников
|
|
4735
|
+
file_type=None, # не используется в режиме нескольких источников
|
|
4736
|
+
update_params=update_params,
|
|
4737
|
+
sql_params=None, # не используется в режиме нескольких источников
|
|
4738
|
+
user_interval=user_interval,
|
|
4739
|
+
filepath=None, # не используется в режиме нескольких источников
|
|
4740
|
+
separator=None, # не используется в режиме нескольких источников
|
|
4741
|
+
increment_dim=increment_dim,
|
|
4742
|
+
interval_dim=interval_dim,
|
|
4743
|
+
interval_borders=interval_borders,
|
|
4744
|
+
encoding=None, # не используется в режиме нескольких источников
|
|
4745
|
+
delayed=delayed,
|
|
4746
|
+
modified_records_params=modified_records_params,
|
|
4747
|
+
relevance_date=relevance_date,
|
|
4748
|
+
indirect_cpu_load_parameter=indirect_cpu_load_parameter,
|
|
4749
|
+
measures=measures,
|
|
4750
|
+
sources=sources,
|
|
4751
|
+
)
|
|
4752
|
+
|
|
4554
4753
|
@timing
|
|
4555
4754
|
def update_cube(
|
|
4556
4755
|
self,
|
|
@@ -4559,12 +4758,12 @@ class BusinessLogic:
|
|
|
4559
4758
|
update_params: dict = None,
|
|
4560
4759
|
user_interval: str = "с текущего дня",
|
|
4561
4760
|
filepath: str = "",
|
|
4562
|
-
separator: str = "",
|
|
4761
|
+
separator: str = ",",
|
|
4563
4762
|
delayed: bool = False,
|
|
4564
4763
|
increment_dim: str = "",
|
|
4565
4764
|
interval_dim: str = "",
|
|
4566
4765
|
interval_borders: list = None,
|
|
4567
|
-
encoding: str = "",
|
|
4766
|
+
encoding: str = "UTF-8",
|
|
4568
4767
|
modified_records_params: dict = None,
|
|
4569
4768
|
relevance_date: dict = None,
|
|
4570
4769
|
indirect_cpu_load_parameter: dict = None,
|
|
@@ -4626,6 +4825,8 @@ class BusinessLogic:
|
|
|
4626
4825
|
используется для замены файла в источнике. Можно заменять на файл того же типа, что и был,
|
|
4627
4826
|
например "csv" на "csv". В пути файла обязательно должно быть расширение, например, ".csv".
|
|
4628
4827
|
:param separator: (str) разделитель столбцов. Обязателен для csv-источника (при замене источника).
|
|
4828
|
+
По умолчанию запятая - ",". Если значение separator не совпадает с разделителем в источнике, возможна
|
|
4829
|
+
ошибка "Error in response: Facts list is empty". В этом случае необходимо поменять значение separator.
|
|
4629
4830
|
:param delayed: (bool) параметр, определяющий, будет ли отложено обновление мультисферы.
|
|
4630
4831
|
Если False, то не будет, и мультисфера будет автоматически обновлена.
|
|
4631
4832
|
Если True: если настроено расписание обновлений (schedule в update_params),
|
|
@@ -4641,7 +4842,7 @@ class BusinessLogic:
|
|
|
4641
4842
|
в список только одно значение времени, а для обновления "с и по указанную дату" - два значения времени,
|
|
4642
4843
|
при этом второе значение должно быть больше первого. Формат значений времени: "DD.MM.YYYY". Все остальные
|
|
4643
4844
|
значения, если они будут переданы, будут игнорироваться. Актуально только для интервального обновления.
|
|
4644
|
-
:param encoding: (str)
|
|
4845
|
+
:param encoding: (str) кодировка; обязательна для csv-источника (при замене источника). По умолчанию - "UTF-8".
|
|
4645
4846
|
:param modified_records_params: (dict) параметры обновления для типа "обновление измененных записей".
|
|
4646
4847
|
Поля, передаваемые в словарь:
|
|
4647
4848
|
"modified_records_key" - поле, которому осуществляется сопоставление данных (имя размерности).
|
|
@@ -4726,7 +4927,7 @@ class BusinessLogic:
|
|
|
4726
4927
|
modified_records_params["version"] = 1
|
|
4727
4928
|
elif algo_version not in (0, 1):
|
|
4728
4929
|
self.logger.warning(f"Param 'modified_records_algo_version' must be 0 or 1, "
|
|
4729
|
-
|
|
4930
|
+
f"not {algo_version}. Changed to 1")
|
|
4730
4931
|
modified_records_params["version"] = 1
|
|
4731
4932
|
cubes_list = self.get_cubes_list()
|
|
4732
4933
|
self.func_name = "update_cube"
|