deepfos 1.1.60__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.
- deepfos/__init__.py +6 -0
- deepfos/_version.py +21 -0
- deepfos/algo/__init__.py +0 -0
- deepfos/algo/graph.py +171 -0
- deepfos/algo/segtree.py +31 -0
- deepfos/api/V1_1/__init__.py +0 -0
- deepfos/api/V1_1/business_model.py +119 -0
- deepfos/api/V1_1/dimension.py +599 -0
- deepfos/api/V1_1/models/__init__.py +0 -0
- deepfos/api/V1_1/models/business_model.py +1033 -0
- deepfos/api/V1_1/models/dimension.py +2768 -0
- deepfos/api/V1_2/__init__.py +0 -0
- deepfos/api/V1_2/dimension.py +285 -0
- deepfos/api/V1_2/models/__init__.py +0 -0
- deepfos/api/V1_2/models/dimension.py +2923 -0
- deepfos/api/__init__.py +0 -0
- deepfos/api/account.py +167 -0
- deepfos/api/accounting_engines.py +147 -0
- deepfos/api/app.py +626 -0
- deepfos/api/approval_process.py +198 -0
- deepfos/api/base.py +983 -0
- deepfos/api/business_model.py +160 -0
- deepfos/api/consolidation.py +129 -0
- deepfos/api/consolidation_process.py +106 -0
- deepfos/api/datatable.py +341 -0
- deepfos/api/deep_pipeline.py +61 -0
- deepfos/api/deepconnector.py +36 -0
- deepfos/api/deepfos_task.py +92 -0
- deepfos/api/deepmodel.py +188 -0
- deepfos/api/dimension.py +486 -0
- deepfos/api/financial_model.py +319 -0
- deepfos/api/journal_model.py +119 -0
- deepfos/api/journal_template.py +132 -0
- deepfos/api/memory_financial_model.py +98 -0
- deepfos/api/models/__init__.py +3 -0
- deepfos/api/models/account.py +483 -0
- deepfos/api/models/accounting_engines.py +756 -0
- deepfos/api/models/app.py +1338 -0
- deepfos/api/models/approval_process.py +1043 -0
- deepfos/api/models/base.py +234 -0
- deepfos/api/models/business_model.py +805 -0
- deepfos/api/models/consolidation.py +711 -0
- deepfos/api/models/consolidation_process.py +248 -0
- deepfos/api/models/datatable_mysql.py +427 -0
- deepfos/api/models/deep_pipeline.py +55 -0
- deepfos/api/models/deepconnector.py +28 -0
- deepfos/api/models/deepfos_task.py +386 -0
- deepfos/api/models/deepmodel.py +308 -0
- deepfos/api/models/dimension.py +1576 -0
- deepfos/api/models/financial_model.py +1796 -0
- deepfos/api/models/journal_model.py +341 -0
- deepfos/api/models/journal_template.py +854 -0
- deepfos/api/models/memory_financial_model.py +478 -0
- deepfos/api/models/platform.py +178 -0
- deepfos/api/models/python.py +221 -0
- deepfos/api/models/reconciliation_engine.py +411 -0
- deepfos/api/models/reconciliation_report.py +161 -0
- deepfos/api/models/role_strategy.py +884 -0
- deepfos/api/models/smartlist.py +237 -0
- deepfos/api/models/space.py +1137 -0
- deepfos/api/models/system.py +1065 -0
- deepfos/api/models/variable.py +463 -0
- deepfos/api/models/workflow.py +946 -0
- deepfos/api/platform.py +199 -0
- deepfos/api/python.py +90 -0
- deepfos/api/reconciliation_engine.py +181 -0
- deepfos/api/reconciliation_report.py +64 -0
- deepfos/api/role_strategy.py +234 -0
- deepfos/api/smartlist.py +69 -0
- deepfos/api/space.py +582 -0
- deepfos/api/system.py +372 -0
- deepfos/api/variable.py +154 -0
- deepfos/api/workflow.py +264 -0
- deepfos/boost/__init__.py +6 -0
- deepfos/boost/py_jstream.py +89 -0
- deepfos/boost/py_pandas.py +20 -0
- deepfos/cache.py +121 -0
- deepfos/config.py +6 -0
- deepfos/core/__init__.py +27 -0
- deepfos/core/cube/__init__.py +10 -0
- deepfos/core/cube/_base.py +462 -0
- deepfos/core/cube/constants.py +21 -0
- deepfos/core/cube/cube.py +408 -0
- deepfos/core/cube/formula.py +707 -0
- deepfos/core/cube/syscube.py +532 -0
- deepfos/core/cube/typing.py +7 -0
- deepfos/core/cube/utils.py +238 -0
- deepfos/core/dimension/__init__.py +11 -0
- deepfos/core/dimension/_base.py +506 -0
- deepfos/core/dimension/dimcreator.py +184 -0
- deepfos/core/dimension/dimension.py +472 -0
- deepfos/core/dimension/dimexpr.py +271 -0
- deepfos/core/dimension/dimmember.py +155 -0
- deepfos/core/dimension/eledimension.py +22 -0
- deepfos/core/dimension/filters.py +99 -0
- deepfos/core/dimension/sysdimension.py +168 -0
- deepfos/core/logictable/__init__.py +5 -0
- deepfos/core/logictable/_cache.py +141 -0
- deepfos/core/logictable/_operator.py +663 -0
- deepfos/core/logictable/nodemixin.py +673 -0
- deepfos/core/logictable/sqlcondition.py +609 -0
- deepfos/core/logictable/tablemodel.py +497 -0
- deepfos/db/__init__.py +36 -0
- deepfos/db/cipher.py +660 -0
- deepfos/db/clickhouse.py +191 -0
- deepfos/db/connector.py +195 -0
- deepfos/db/daclickhouse.py +171 -0
- deepfos/db/dameng.py +101 -0
- deepfos/db/damysql.py +189 -0
- deepfos/db/dbkits.py +358 -0
- deepfos/db/deepengine.py +99 -0
- deepfos/db/deepmodel.py +82 -0
- deepfos/db/deepmodel_kingbase.py +83 -0
- deepfos/db/edb.py +214 -0
- deepfos/db/gauss.py +83 -0
- deepfos/db/kingbase.py +83 -0
- deepfos/db/mysql.py +184 -0
- deepfos/db/oracle.py +131 -0
- deepfos/db/postgresql.py +192 -0
- deepfos/db/sqlserver.py +99 -0
- deepfos/db/utils.py +135 -0
- deepfos/element/__init__.py +89 -0
- deepfos/element/accounting.py +348 -0
- deepfos/element/apvlprocess.py +215 -0
- deepfos/element/base.py +398 -0
- deepfos/element/bizmodel.py +1269 -0
- deepfos/element/datatable.py +2467 -0
- deepfos/element/deep_pipeline.py +186 -0
- deepfos/element/deepconnector.py +59 -0
- deepfos/element/deepmodel.py +1806 -0
- deepfos/element/dimension.py +1254 -0
- deepfos/element/fact_table.py +427 -0
- deepfos/element/finmodel.py +1485 -0
- deepfos/element/journal.py +840 -0
- deepfos/element/journal_template.py +943 -0
- deepfos/element/pyscript.py +412 -0
- deepfos/element/reconciliation.py +553 -0
- deepfos/element/rolestrategy.py +243 -0
- deepfos/element/smartlist.py +457 -0
- deepfos/element/variable.py +756 -0
- deepfos/element/workflow.py +560 -0
- deepfos/exceptions/__init__.py +239 -0
- deepfos/exceptions/hook.py +86 -0
- deepfos/lazy.py +104 -0
- deepfos/lazy_import.py +84 -0
- deepfos/lib/__init__.py +0 -0
- deepfos/lib/_javaobj.py +366 -0
- deepfos/lib/asynchronous.py +879 -0
- deepfos/lib/concurrency.py +107 -0
- deepfos/lib/constant.py +39 -0
- deepfos/lib/decorator.py +310 -0
- deepfos/lib/deepchart.py +778 -0
- deepfos/lib/deepux.py +477 -0
- deepfos/lib/discovery.py +273 -0
- deepfos/lib/edb_lexer.py +789 -0
- deepfos/lib/eureka.py +156 -0
- deepfos/lib/filterparser.py +751 -0
- deepfos/lib/httpcli.py +106 -0
- deepfos/lib/jsonstreamer.py +80 -0
- deepfos/lib/msg.py +394 -0
- deepfos/lib/nacos.py +225 -0
- deepfos/lib/patch.py +92 -0
- deepfos/lib/redis.py +241 -0
- deepfos/lib/serutils.py +181 -0
- deepfos/lib/stopwatch.py +99 -0
- deepfos/lib/subtask.py +572 -0
- deepfos/lib/sysutils.py +703 -0
- deepfos/lib/utils.py +1003 -0
- deepfos/local.py +160 -0
- deepfos/options.py +670 -0
- deepfos/translation.py +237 -0
- deepfos-1.1.60.dist-info/METADATA +33 -0
- deepfos-1.1.60.dist-info/RECORD +175 -0
- deepfos-1.1.60.dist-info/WHEEL +5 -0
- deepfos-1.1.60.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,756 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
from typing import List, Dict, Union, Any, Callable, TYPE_CHECKING
|
|
3
|
+
import pandas as pd
|
|
4
|
+
import datetime
|
|
5
|
+
|
|
6
|
+
from deepfos.api.models.variable import VariableValueDTO, VariableVO, UpdateVariavlesDTO, ValueTypeMapDTO, \
|
|
7
|
+
BaseElementDetail
|
|
8
|
+
from deepfos.api.variable import VariableAPI
|
|
9
|
+
from deepfos.element.base import ElementBase, SyncMeta
|
|
10
|
+
from deepfos.element.dimension import Dimension
|
|
11
|
+
from deepfos.element.smartlist import SmartList
|
|
12
|
+
from deepfos.exceptions import VariableUpdateError, VariableCreateError
|
|
13
|
+
from deepfos.lib.utils import Group, GroupDict
|
|
14
|
+
from deepfos.lib.constant import UNSET
|
|
15
|
+
from deepfos.lib.asynchronous import future_property
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
__all__ = [
|
|
19
|
+
'Variable',
|
|
20
|
+
'AsyncVariable',
|
|
21
|
+
'DateType'
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class GlobalVariable(VariableValueDTO):
|
|
26
|
+
description: dict = {'zh-cn': None, 'en': None}
|
|
27
|
+
scope: int = 1
|
|
28
|
+
status: bool = True
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class UserVariable(VariableValueDTO):
|
|
32
|
+
description: dict = {'zh-cn': None, 'en': None}
|
|
33
|
+
scope: int = 2
|
|
34
|
+
status: bool = True
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
class VariableTypeId(int, Enum):
|
|
38
|
+
#: TEXT - 文本
|
|
39
|
+
TEXT = 1
|
|
40
|
+
#: NUMBER - 数字
|
|
41
|
+
NUMBER = 15
|
|
42
|
+
#: SML - 值列表
|
|
43
|
+
SML = 3
|
|
44
|
+
#: DIM - 维度
|
|
45
|
+
DIM = 8
|
|
46
|
+
#: DATE - 日期时间
|
|
47
|
+
DATE = 11
|
|
48
|
+
#: CUSTOM_LIST - 自定义列表
|
|
49
|
+
CUSTOM_LIST = 13
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class DateType(str, Enum):
|
|
53
|
+
#: 年
|
|
54
|
+
year = "1"
|
|
55
|
+
#: 年月
|
|
56
|
+
year_month = "2"
|
|
57
|
+
#: 年月日
|
|
58
|
+
year_month_day = "3"
|
|
59
|
+
#: 年月日时间
|
|
60
|
+
year_month_day_time = "4"
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class TextValueMap(ValueTypeMapDTO):
|
|
64
|
+
#: 变量类型代码
|
|
65
|
+
valueType: int = VariableTypeId.TEXT
|
|
66
|
+
valueKey: str = "1"
|
|
67
|
+
#: 文本长度
|
|
68
|
+
length: int = 255
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class NumberValueMap(ValueTypeMapDTO):
|
|
72
|
+
#: 变量类型代码
|
|
73
|
+
valueType: int = VariableTypeId.NUMBER
|
|
74
|
+
#: 整数长度
|
|
75
|
+
maxLen: int = None
|
|
76
|
+
#: 小数长度
|
|
77
|
+
digitLen: int = None
|
|
78
|
+
#: 允许等于最小值
|
|
79
|
+
minEqual: bool = True
|
|
80
|
+
#: 最小值
|
|
81
|
+
minimun: int = None
|
|
82
|
+
#: 允许等于最大值
|
|
83
|
+
maxEqual: bool = True
|
|
84
|
+
#: 最大值
|
|
85
|
+
maximun: int = None
|
|
86
|
+
#: 是否显示为百分比
|
|
87
|
+
percentage: bool = False
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class SmartListValueMap(ValueTypeMapDTO):
|
|
91
|
+
#: 变量类型代码
|
|
92
|
+
valueType: int = VariableTypeId.SML
|
|
93
|
+
#: 元素详情(由smartlist提取后的元素信息)
|
|
94
|
+
elementDetail: BaseElementDetail = None
|
|
95
|
+
#: 值列表元素名称
|
|
96
|
+
valueKey: str = None
|
|
97
|
+
#: 是否选择多个值列表成员
|
|
98
|
+
selectedMulti: bool = False
|
|
99
|
+
#: 多选值列表的成员值列表
|
|
100
|
+
valueField: List[str] = []
|
|
101
|
+
#: 多选成员数上限
|
|
102
|
+
multipleChoiceLimit: int = None
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class DimensionValueMap(ValueTypeMapDTO):
|
|
106
|
+
#: 变量类型代码
|
|
107
|
+
valueType: int = VariableTypeId.DIM
|
|
108
|
+
#: 元素详情(由Dimension提取后的元素信息)
|
|
109
|
+
elementDetail: BaseElementDetail = None
|
|
110
|
+
#: 维度元素名称
|
|
111
|
+
dimensionName: str = None
|
|
112
|
+
#: 维度表达式
|
|
113
|
+
valueKey: str = None
|
|
114
|
+
#: 是否选择多个值列表成员
|
|
115
|
+
selectedMulti: bool = False
|
|
116
|
+
#: 多选成员数上限
|
|
117
|
+
multipleChoiceLimit: int = None
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
class DateValueMap(ValueTypeMapDTO):
|
|
121
|
+
#: 变量类型代码
|
|
122
|
+
valueType: int = VariableTypeId.DATE
|
|
123
|
+
#: 对应年份格式的编号字符串
|
|
124
|
+
valueKey: str = DateType.year_month_day_time
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class CustomListValueMap(ValueTypeMapDTO):
|
|
128
|
+
#: 变量类型代码
|
|
129
|
+
valueType: int = VariableTypeId.CUSTOM_LIST
|
|
130
|
+
#: 自定义列表表达式(多个值请用“,”分开。示例: 1,2,3)
|
|
131
|
+
valueKey: str = None
|
|
132
|
+
#: 是否选择多个值列表成员
|
|
133
|
+
selectedMulti: bool = False
|
|
134
|
+
#: 多选成员数上限
|
|
135
|
+
multipleChoiceLimit: int = None
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
# -----------------------------------------------------------------------------
|
|
139
|
+
# typing
|
|
140
|
+
T_Number = Union[int, float]
|
|
141
|
+
T_Date = Union[pd.Timestamp, datetime.datetime, str]
|
|
142
|
+
T_Variable = Union[GlobalVariable, UserVariable]
|
|
143
|
+
T_VarValue = Union[T_Number, T_Date, List[str]]
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def value_adaptor(var_type: int) -> Callable[[Any], str]:
|
|
147
|
+
if var_type == VariableTypeId.DATE:
|
|
148
|
+
def handle(value: T_Date):
|
|
149
|
+
if not isinstance(value, str):
|
|
150
|
+
value = value.strftime('%Y-%m-%d %H:%M:%S')
|
|
151
|
+
return value
|
|
152
|
+
elif var_type == VariableTypeId.NUMBER:
|
|
153
|
+
def handle(value: T_Number):
|
|
154
|
+
return str(value)
|
|
155
|
+
else:
|
|
156
|
+
def handle(value: Union[str, List[str]]):
|
|
157
|
+
if isinstance(value, list):
|
|
158
|
+
value = ','.join(map(str, value))
|
|
159
|
+
return value
|
|
160
|
+
|
|
161
|
+
def guard_none_handle(value):
|
|
162
|
+
if value is None:
|
|
163
|
+
return value
|
|
164
|
+
else:
|
|
165
|
+
return handle(value)
|
|
166
|
+
|
|
167
|
+
return guard_none_handle
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
# -----------------------------------------------------------------------------
|
|
171
|
+
# core
|
|
172
|
+
class AsyncVariable(ElementBase[VariableAPI]):
|
|
173
|
+
"""变量
|
|
174
|
+
|
|
175
|
+
为了防止将变量元素本身与变量元素保存的变量值混淆。在本节文档中,
|
|
176
|
+
将变量元素称为 **“变量”** ,各变量值称为 **“变量成员”** 或简称为 **“成员”**。
|
|
177
|
+
"""
|
|
178
|
+
def __init__(
|
|
179
|
+
self,
|
|
180
|
+
element_name: str,
|
|
181
|
+
folder_id: str = None,
|
|
182
|
+
path: str = None,
|
|
183
|
+
server_name: str = None,
|
|
184
|
+
):
|
|
185
|
+
self.__group = Group()
|
|
186
|
+
self.__description = None
|
|
187
|
+
self.__gv_memo = None
|
|
188
|
+
self.__uv_memo = None
|
|
189
|
+
super().__init__(element_name=element_name, folder_id=folder_id, path=path, server_name=server_name)
|
|
190
|
+
|
|
191
|
+
@property
|
|
192
|
+
def _group(self) -> Group:
|
|
193
|
+
if self.__gv_memo is None:
|
|
194
|
+
_ = self._gv_memo
|
|
195
|
+
if self.__uv_memo is None:
|
|
196
|
+
_ = self._uv_memo
|
|
197
|
+
return self.__group
|
|
198
|
+
|
|
199
|
+
@property
|
|
200
|
+
def _gv_memo(self) -> GroupDict[str, GlobalVariable]:
|
|
201
|
+
if self.__gv_memo is None:
|
|
202
|
+
self.__gv_memo = GroupDict(self.__group)
|
|
203
|
+
for gv in self.meta.globalVariables:
|
|
204
|
+
self.__gv_memo[gv.name] = gv
|
|
205
|
+
|
|
206
|
+
return self.__gv_memo
|
|
207
|
+
|
|
208
|
+
@property
|
|
209
|
+
def _uv_memo(self) -> GroupDict[str, UserVariable]:
|
|
210
|
+
if self.__uv_memo is None:
|
|
211
|
+
self.__uv_memo = GroupDict(self.__group)
|
|
212
|
+
for uv in self.meta.userVariables:
|
|
213
|
+
self.__uv_memo[uv.name] = uv
|
|
214
|
+
|
|
215
|
+
return self.__uv_memo
|
|
216
|
+
|
|
217
|
+
@property
|
|
218
|
+
def _description(self) -> Dict[str, str]:
|
|
219
|
+
if not self.__description:
|
|
220
|
+
self.__description = self.meta.description
|
|
221
|
+
|
|
222
|
+
return self.__description
|
|
223
|
+
|
|
224
|
+
@future_property
|
|
225
|
+
async def meta(self) -> VariableVO:
|
|
226
|
+
"""系统中的变量列表的元数据信息"""
|
|
227
|
+
api = await self.wait_for('async_api')
|
|
228
|
+
ele_info = await self.wait_for('element_info')
|
|
229
|
+
return await api.variable.query(
|
|
230
|
+
folderId=ele_info.folderId,
|
|
231
|
+
elementName=ele_info.elementName,
|
|
232
|
+
)
|
|
233
|
+
|
|
234
|
+
def __getitem__(self, name: str) -> T_VarValue:
|
|
235
|
+
"""
|
|
236
|
+
根据变量成员名获取成员值
|
|
237
|
+
|
|
238
|
+
当为用户变量时,返回自定义变量
|
|
239
|
+
|
|
240
|
+
Args:
|
|
241
|
+
name: 变量成员名
|
|
242
|
+
|
|
243
|
+
Returns:
|
|
244
|
+
变量的值
|
|
245
|
+
|
|
246
|
+
See Also:
|
|
247
|
+
- :meth:`get`
|
|
248
|
+
- :meth:`get_value`
|
|
249
|
+
|
|
250
|
+
"""
|
|
251
|
+
return self.get_value(name, is_customize_value=True)
|
|
252
|
+
|
|
253
|
+
def get(self, name: str, default: str = None) -> T_VarValue:
|
|
254
|
+
"""
|
|
255
|
+
根据变量成员名获取成员值
|
|
256
|
+
|
|
257
|
+
当为用户变量时,返回自定义变量
|
|
258
|
+
|
|
259
|
+
Args:
|
|
260
|
+
name: 变量成员名
|
|
261
|
+
default: 变量名不存在时的默认值
|
|
262
|
+
|
|
263
|
+
Returns:
|
|
264
|
+
变量的值
|
|
265
|
+
|
|
266
|
+
See Also:
|
|
267
|
+
:meth:`get_value`
|
|
268
|
+
|
|
269
|
+
"""
|
|
270
|
+
return self.get_value(name, is_customize_value=True, default=default)
|
|
271
|
+
|
|
272
|
+
@staticmethod
|
|
273
|
+
def _maybe_list(value, cast: Callable[[str], Any] = None):
|
|
274
|
+
if not value:
|
|
275
|
+
return value
|
|
276
|
+
if cast is None:
|
|
277
|
+
cast = lambda x: x
|
|
278
|
+
if len(val_list := value.split(',')) == 1:
|
|
279
|
+
return cast(val_list[0])
|
|
280
|
+
return [cast(val) for val in val_list]
|
|
281
|
+
|
|
282
|
+
def get_value(
|
|
283
|
+
self,
|
|
284
|
+
name: str,
|
|
285
|
+
is_customize_value: bool = True,
|
|
286
|
+
default: Any = UNSET,
|
|
287
|
+
auto_cast: bool = True,
|
|
288
|
+
obj_hook: Callable[[str], Any] = None
|
|
289
|
+
) -> T_VarValue:
|
|
290
|
+
"""
|
|
291
|
+
根据变量成员名获取成员值
|
|
292
|
+
|
|
293
|
+
Args:
|
|
294
|
+
name: 变量成员名
|
|
295
|
+
is_customize_value: 是否为用户变量时配置的自定义值,在获取用户变量时会查看该值
|
|
296
|
+
default: 变量不存在时的默认值
|
|
297
|
+
auto_cast: 是否对变量值做自动转换
|
|
298
|
+
obj_hook: 自定义的变量转换函数
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
.. admonition:: 示例
|
|
302
|
+
|
|
303
|
+
例如变量成员 ``ctm_list`` 为自定义列表,存的值为1,2,3。
|
|
304
|
+
在使用默认参数的情况下,此方法将返回 ['1', '2', '3']。
|
|
305
|
+
|
|
306
|
+
如果希望返回整数列表[1, 2, 3],可以传入 ``obj_hook`` 使用自定义逻辑
|
|
307
|
+
|
|
308
|
+
.. code-block:: python
|
|
309
|
+
|
|
310
|
+
var = Variable('test_var')
|
|
311
|
+
|
|
312
|
+
def hook(value):
|
|
313
|
+
return [int(v) for v in value.split(',')]
|
|
314
|
+
|
|
315
|
+
var.get_value('ctm_list', obj_hook=hook)
|
|
316
|
+
|
|
317
|
+
Returns:
|
|
318
|
+
变量的值
|
|
319
|
+
"""
|
|
320
|
+
if name in self._gv_memo:
|
|
321
|
+
var = self._gv_memo[name]
|
|
322
|
+
is_customize_value = False
|
|
323
|
+
elif name in self._uv_memo:
|
|
324
|
+
var = self._uv_memo[name]
|
|
325
|
+
elif default is UNSET:
|
|
326
|
+
raise KeyError(f"Variable : {name} not exist.")
|
|
327
|
+
else:
|
|
328
|
+
return default
|
|
329
|
+
|
|
330
|
+
value = var.userValue if is_customize_value else var.value
|
|
331
|
+
|
|
332
|
+
if obj_hook is not None:
|
|
333
|
+
return obj_hook(value)
|
|
334
|
+
|
|
335
|
+
if not auto_cast:
|
|
336
|
+
cast = None
|
|
337
|
+
elif var.valueType == VariableTypeId.NUMBER:
|
|
338
|
+
cast = float
|
|
339
|
+
elif var.valueType == VariableTypeId.DATE:
|
|
340
|
+
cast = pd.to_datetime
|
|
341
|
+
else:
|
|
342
|
+
cast = None
|
|
343
|
+
|
|
344
|
+
return self._maybe_list(value, cast)
|
|
345
|
+
|
|
346
|
+
def __setitem__(self, key: str, value: T_VarValue):
|
|
347
|
+
"""更新变量成员的值
|
|
348
|
+
|
|
349
|
+
根据变量名称与变量值,更新变量的值。全局变量时即为变量的值,
|
|
350
|
+
|
|
351
|
+
"""
|
|
352
|
+
self.update_value(key, value, is_customize_value=True)
|
|
353
|
+
|
|
354
|
+
def update_value(
|
|
355
|
+
self,
|
|
356
|
+
name: str,
|
|
357
|
+
update_value: T_VarValue,
|
|
358
|
+
is_customize_value: bool = True
|
|
359
|
+
):
|
|
360
|
+
"""更新变量成员的值
|
|
361
|
+
|
|
362
|
+
根据变量名称与变量值,更新变量的值。全局变量时即为变量的值,
|
|
363
|
+
用户变量时即为自定义值,为用户变量默认值时,需置 ``is_customize_value`` 为
|
|
364
|
+
``False``
|
|
365
|
+
|
|
366
|
+
Args:
|
|
367
|
+
name: 变量成员名称
|
|
368
|
+
update_value: 需更新的值
|
|
369
|
+
is_customize_value: 是否更新自定义值(仅对用户变量生效)
|
|
370
|
+
"""
|
|
371
|
+
variable = self.get_variable(name)
|
|
372
|
+
value = value_adaptor(variable.valueType)(update_value)
|
|
373
|
+
|
|
374
|
+
if is_customize_value and name in self._uv_memo:
|
|
375
|
+
variable.userValue = value
|
|
376
|
+
else:
|
|
377
|
+
variable.value = value
|
|
378
|
+
|
|
379
|
+
async def save(self):
|
|
380
|
+
"""
|
|
381
|
+
保存变量
|
|
382
|
+
|
|
383
|
+
将当前元素内变量信息保存至系统
|
|
384
|
+
"""
|
|
385
|
+
payload = UpdateVariavlesDTO.construct_from(
|
|
386
|
+
self.meta, description=self._description,
|
|
387
|
+
globalVariables=list(self._gv_memo.values()),
|
|
388
|
+
userVariables=list(self._uv_memo.values()),
|
|
389
|
+
moduleId=self.api.module_id
|
|
390
|
+
)
|
|
391
|
+
return await self._update_impl(payload=payload)
|
|
392
|
+
|
|
393
|
+
async def _update_impl(self, payload: UpdateVariavlesDTO):
|
|
394
|
+
await self.async_api.variable.update(payload)
|
|
395
|
+
# 使memo的缓存失效
|
|
396
|
+
self.__gv_memo = None
|
|
397
|
+
self.__uv_memo = None
|
|
398
|
+
self.__description = None
|
|
399
|
+
self.__group.clear()
|
|
400
|
+
# 使meta重置
|
|
401
|
+
self.__class__.meta.reset(self)
|
|
402
|
+
|
|
403
|
+
@property
|
|
404
|
+
def variables(self) -> Dict[str, T_Variable]:
|
|
405
|
+
"""
|
|
406
|
+
所有变量成员
|
|
407
|
+
|
|
408
|
+
Returns:
|
|
409
|
+
以name为键名,Variable为内容的字典
|
|
410
|
+
"""
|
|
411
|
+
all_variable = {}
|
|
412
|
+
if self._gv_memo:
|
|
413
|
+
all_variable.update(self._gv_memo)
|
|
414
|
+
if self._uv_memo:
|
|
415
|
+
all_variable.update(self._uv_memo)
|
|
416
|
+
return all_variable
|
|
417
|
+
|
|
418
|
+
def get_variable(self, name: str) -> T_Variable:
|
|
419
|
+
"""
|
|
420
|
+
根据变量成员名获取成员
|
|
421
|
+
|
|
422
|
+
Args:
|
|
423
|
+
name: 变量成员名
|
|
424
|
+
|
|
425
|
+
Returns:
|
|
426
|
+
GlobalVariable或UserVariable类型的对象
|
|
427
|
+
"""
|
|
428
|
+
if name in self._gv_memo:
|
|
429
|
+
return self._gv_memo[name]
|
|
430
|
+
elif name in self._uv_memo:
|
|
431
|
+
return self._uv_memo[name]
|
|
432
|
+
else:
|
|
433
|
+
raise KeyError(f"Variable : {name} not exist.")
|
|
434
|
+
|
|
435
|
+
def _add_variable(
|
|
436
|
+
self,
|
|
437
|
+
name: str,
|
|
438
|
+
value_map: Union[
|
|
439
|
+
TextValueMap, NumberValueMap, SmartListValueMap,
|
|
440
|
+
DimensionValueMap, DateValueMap, CustomListValueMap
|
|
441
|
+
],
|
|
442
|
+
value: Union[str, List[str]],
|
|
443
|
+
description: Dict[str, str],
|
|
444
|
+
is_global: bool,
|
|
445
|
+
is_customize_value: bool
|
|
446
|
+
):
|
|
447
|
+
"""新增单个变量
|
|
448
|
+
|
|
449
|
+
Args:
|
|
450
|
+
name: 变量成员名
|
|
451
|
+
value_map: 变量类型
|
|
452
|
+
value: 变量值
|
|
453
|
+
description: 变量描述
|
|
454
|
+
is_global: 是否为全局变量
|
|
455
|
+
is_customize_value: 值是否为用户变量时配置的自定义值
|
|
456
|
+
"""
|
|
457
|
+
if name in self._group.keys():
|
|
458
|
+
raise VariableCreateError(f"Variable: {name} already exist. "
|
|
459
|
+
"Please use update instead.")
|
|
460
|
+
if is_global:
|
|
461
|
+
self._gv_memo[name] = variable = \
|
|
462
|
+
GlobalVariable(
|
|
463
|
+
name=name,
|
|
464
|
+
valueType=value_map.valueType,
|
|
465
|
+
valueTypeMap=value_map
|
|
466
|
+
)
|
|
467
|
+
else:
|
|
468
|
+
self._uv_memo[name] = variable = \
|
|
469
|
+
UserVariable(
|
|
470
|
+
name=name,
|
|
471
|
+
valueType=value_map.valueType,
|
|
472
|
+
valueTypeMap=value_map
|
|
473
|
+
)
|
|
474
|
+
|
|
475
|
+
if description:
|
|
476
|
+
variable.description = description
|
|
477
|
+
|
|
478
|
+
if value:
|
|
479
|
+
self.update_value(name, value, is_customize_value)
|
|
480
|
+
|
|
481
|
+
def add_text(
|
|
482
|
+
self,
|
|
483
|
+
name: str,
|
|
484
|
+
value: Union[str, List[str]] = None,
|
|
485
|
+
description: Dict[str, str] = None,
|
|
486
|
+
is_global: bool = False,
|
|
487
|
+
is_customize_value: bool = True,
|
|
488
|
+
length: int = 255
|
|
489
|
+
):
|
|
490
|
+
"""新增单个文本变量成员
|
|
491
|
+
|
|
492
|
+
Args:
|
|
493
|
+
name: 变量成员名
|
|
494
|
+
value: 变量值
|
|
495
|
+
description: 变量描述
|
|
496
|
+
is_global: 是否为全局变量
|
|
497
|
+
is_customize_value: 值是否为用户变量时配置的自定义值
|
|
498
|
+
length: 文本长度
|
|
499
|
+
|
|
500
|
+
"""
|
|
501
|
+
value = value_adaptor(VariableTypeId.TEXT)(value)
|
|
502
|
+
value_map = TextValueMap(length=length)
|
|
503
|
+
self._add_variable(name=name, value_map=value_map, value=value,
|
|
504
|
+
description=description,
|
|
505
|
+
is_customize_value=is_customize_value,
|
|
506
|
+
is_global=is_global)
|
|
507
|
+
|
|
508
|
+
def add_number(
|
|
509
|
+
self,
|
|
510
|
+
name: str,
|
|
511
|
+
value: T_Number = None,
|
|
512
|
+
description: Dict[str, str] = None,
|
|
513
|
+
is_global: bool = False,
|
|
514
|
+
is_customize_value: bool = True,
|
|
515
|
+
int_length: int = 13,
|
|
516
|
+
digit_length: int = 6,
|
|
517
|
+
min_equal: bool = True,
|
|
518
|
+
minimun: int = None,
|
|
519
|
+
max_equal: bool = True,
|
|
520
|
+
maximun: int = None,
|
|
521
|
+
percentage: bool = False
|
|
522
|
+
):
|
|
523
|
+
"""新增单个数字变量成员
|
|
524
|
+
|
|
525
|
+
Args:
|
|
526
|
+
name: 变量成员名
|
|
527
|
+
value: 变量值
|
|
528
|
+
description: 变量描述
|
|
529
|
+
is_global: 是否为全局变量
|
|
530
|
+
is_customize_value: 值是否为用户变量时配置的自定义值
|
|
531
|
+
int_length: 整数长度
|
|
532
|
+
digit_length: 小数长度
|
|
533
|
+
min_equal: 允许等于最小值
|
|
534
|
+
minimun: 最小值
|
|
535
|
+
max_equal: 允许等于最大值
|
|
536
|
+
maximun: 最大值
|
|
537
|
+
percentage: 是否显示为百分比
|
|
538
|
+
|
|
539
|
+
"""
|
|
540
|
+
value = value_adaptor(VariableTypeId.NUMBER)(value)
|
|
541
|
+
value_map = NumberValueMap(maxLen=int_length, digitLen=digit_length, minEqual=min_equal, minimun=minimun,
|
|
542
|
+
maxEqual=max_equal, maximun=maximun, percentage=percentage)
|
|
543
|
+
self._add_variable(name=name, value_map=value_map, value=str(value),
|
|
544
|
+
description=description,
|
|
545
|
+
is_customize_value=is_customize_value,
|
|
546
|
+
is_global=is_global)
|
|
547
|
+
|
|
548
|
+
def add_smartlist(
|
|
549
|
+
self,
|
|
550
|
+
name: str,
|
|
551
|
+
smart_list: SmartList,
|
|
552
|
+
value: Union[str, List[str]] = None,
|
|
553
|
+
description: Dict[str, str] = None,
|
|
554
|
+
is_global: bool = False,
|
|
555
|
+
is_customize_value: bool = True,
|
|
556
|
+
selected_multi: bool = False,
|
|
557
|
+
multi_member_list: List[str] = None,
|
|
558
|
+
multiple_choice_limit: int = None
|
|
559
|
+
):
|
|
560
|
+
"""新增单个值列表变量成员
|
|
561
|
+
|
|
562
|
+
Args:
|
|
563
|
+
name: 变量成员名
|
|
564
|
+
smart_list: 值列表对象(必填)
|
|
565
|
+
value: 变量值
|
|
566
|
+
description: 变量描述
|
|
567
|
+
is_global: 是否为全局变量
|
|
568
|
+
is_customize_value: 值是否为用户变量时配置的自定义值
|
|
569
|
+
selected_multi: 是否选择多个值列表成员
|
|
570
|
+
multi_member_list: 多选值列表的成员值列表
|
|
571
|
+
multiple_choice_limit: 多选成员数上限
|
|
572
|
+
"""
|
|
573
|
+
if multi_member_list is None:
|
|
574
|
+
multi_member_list = []
|
|
575
|
+
|
|
576
|
+
value = value_adaptor(VariableTypeId.SML)(value)
|
|
577
|
+
|
|
578
|
+
element_detail = BaseElementDetail.construct_from(smart_list.element_info, elementType="SML")
|
|
579
|
+
value_map = SmartListValueMap(elementDetail=element_detail,
|
|
580
|
+
valueKey=smart_list.element_info.elementName,
|
|
581
|
+
selectedMulti=selected_multi,
|
|
582
|
+
valueField=multi_member_list,
|
|
583
|
+
multipleChoiceLimit=multiple_choice_limit)
|
|
584
|
+
|
|
585
|
+
self._add_variable(name=name, value_map=value_map, value=value,
|
|
586
|
+
description=description,
|
|
587
|
+
is_customize_value=is_customize_value,
|
|
588
|
+
is_global=is_global)
|
|
589
|
+
|
|
590
|
+
def add_dimension(
|
|
591
|
+
self,
|
|
592
|
+
name: str,
|
|
593
|
+
dim: Dimension,
|
|
594
|
+
dim_expression: str,
|
|
595
|
+
value: Union[str, List[str]] = None,
|
|
596
|
+
description: Dict[str, str] = None,
|
|
597
|
+
is_global: bool = False,
|
|
598
|
+
is_customize_value: bool = True,
|
|
599
|
+
selected_multi: bool = False,
|
|
600
|
+
multiple_choice_limit: int = None
|
|
601
|
+
):
|
|
602
|
+
"""新增单个维度变量成员
|
|
603
|
+
|
|
604
|
+
Args:
|
|
605
|
+
name: 变量成员名
|
|
606
|
+
dim: 维度对象(必填)
|
|
607
|
+
dim_expression: 维度表达式(必填)
|
|
608
|
+
value: 变量值
|
|
609
|
+
description: 变量描述
|
|
610
|
+
is_global: 是否为全局变量
|
|
611
|
+
is_customize_value: 值是否为用户变量时配置的自定义值
|
|
612
|
+
selected_multi: 是否选择多个值列表成员
|
|
613
|
+
multiple_choice_limit: 多选成员数上限
|
|
614
|
+
"""
|
|
615
|
+
|
|
616
|
+
value = value_adaptor(VariableTypeId.DIM)(value)
|
|
617
|
+
element_detail = BaseElementDetail.construct_from(dim.element_info, elementType="DIM")
|
|
618
|
+
value_map = DimensionValueMap(elementDetail=element_detail,
|
|
619
|
+
dimensionName=dim.element_info.elementName,
|
|
620
|
+
valueKey=dim_expression,
|
|
621
|
+
selectedMulti=selected_multi,
|
|
622
|
+
multipleChoiceLimit=multiple_choice_limit)
|
|
623
|
+
|
|
624
|
+
self._add_variable(name=name, value_map=value_map, value=value,
|
|
625
|
+
description=description,
|
|
626
|
+
is_customize_value=is_customize_value,
|
|
627
|
+
is_global=is_global)
|
|
628
|
+
|
|
629
|
+
def add_date(
|
|
630
|
+
self,
|
|
631
|
+
name: str,
|
|
632
|
+
date_format: str = DateType.year_month_day_time,
|
|
633
|
+
value: T_Date = None,
|
|
634
|
+
description: Dict[str, str] = None,
|
|
635
|
+
is_global: bool = False,
|
|
636
|
+
is_customize_value: bool = True
|
|
637
|
+
):
|
|
638
|
+
"""新增单个日期变量成员
|
|
639
|
+
|
|
640
|
+
Args:
|
|
641
|
+
name: 变量成员名
|
|
642
|
+
value: 变量值
|
|
643
|
+
date_format: 对应年份格式的编号(必填,建议使用枚举类DateType的值)
|
|
644
|
+
description: 变量描述
|
|
645
|
+
is_global: 是否为全局变量
|
|
646
|
+
is_customize_value: 值是否为用户变量时配置的自定义值
|
|
647
|
+
|
|
648
|
+
"""
|
|
649
|
+
value = value_adaptor(VariableTypeId.DATE)(value)
|
|
650
|
+
value_map = DateValueMap(valueKey=date_format)
|
|
651
|
+
self._add_variable(name=name, value_map=value_map, value=value,
|
|
652
|
+
description=description,
|
|
653
|
+
is_customize_value=is_customize_value,
|
|
654
|
+
is_global=is_global)
|
|
655
|
+
|
|
656
|
+
def add_custom_list(
|
|
657
|
+
self,
|
|
658
|
+
name: str,
|
|
659
|
+
custom_list: List[Union[int, float]],
|
|
660
|
+
value: Union[str, List[str]] = None,
|
|
661
|
+
description: Dict[str, str] = None,
|
|
662
|
+
is_global: bool = False,
|
|
663
|
+
is_customize_value: bool = True,
|
|
664
|
+
selected_multi: bool = False,
|
|
665
|
+
multiple_choice_limit: int = None
|
|
666
|
+
):
|
|
667
|
+
"""新增单个自定义列表变量成员
|
|
668
|
+
|
|
669
|
+
Args:
|
|
670
|
+
name: 变量成员名
|
|
671
|
+
custom_list: 自定义列表
|
|
672
|
+
value: 变量值
|
|
673
|
+
description: 变量描述
|
|
674
|
+
is_global: 是否为全局变量
|
|
675
|
+
is_customize_value: 值是否为用户变量时配置的自定义值
|
|
676
|
+
selected_multi: 是否选择多个值列表成员
|
|
677
|
+
multiple_choice_limit: 多选成员数上限
|
|
678
|
+
|
|
679
|
+
"""
|
|
680
|
+
value = value_adaptor(VariableTypeId.CUSTOM_LIST)(value)
|
|
681
|
+
list_expr = ','.join(map(str, custom_list))
|
|
682
|
+
value_map = CustomListValueMap(valueKey=list_expr,
|
|
683
|
+
selectedMulti=selected_multi,
|
|
684
|
+
multipleChoiceLimit=multiple_choice_limit)
|
|
685
|
+
self._add_variable(name=name, value_map=value_map, value=value,
|
|
686
|
+
description=description,
|
|
687
|
+
is_customize_value=is_customize_value,
|
|
688
|
+
is_global=is_global)
|
|
689
|
+
|
|
690
|
+
def _update_valuetype(
|
|
691
|
+
self,
|
|
692
|
+
name,
|
|
693
|
+
value_map: Union[
|
|
694
|
+
TextValueMap, NumberValueMap, SmartListValueMap,
|
|
695
|
+
DimensionValueMap, DateValueMap, CustomListValueMap]
|
|
696
|
+
):
|
|
697
|
+
"""根据变量名称与变量值,更新变量的变量类型(逻辑属性)
|
|
698
|
+
|
|
699
|
+
Args:
|
|
700
|
+
name: 变量成员名
|
|
701
|
+
value_map: 变量类型(逻辑属性)
|
|
702
|
+
"""
|
|
703
|
+
variable = self.get_variable(name)
|
|
704
|
+
variable.valueType = value_map.valueType
|
|
705
|
+
variable.valueTypeMap = value_map
|
|
706
|
+
|
|
707
|
+
def update_description(
|
|
708
|
+
self,
|
|
709
|
+
name: str,
|
|
710
|
+
en_description: str = None,
|
|
711
|
+
zh_cn_description: str = None
|
|
712
|
+
):
|
|
713
|
+
"""根据变量成员名称,更新变量成员的描述
|
|
714
|
+
|
|
715
|
+
Args:
|
|
716
|
+
name: 变量成员名
|
|
717
|
+
en_description: 变量英文描述
|
|
718
|
+
zh_cn_description: 变量中文描述
|
|
719
|
+
"""
|
|
720
|
+
description = {'zh-cn': zh_cn_description, 'en': en_description}
|
|
721
|
+
variable = self.get_variable(name)
|
|
722
|
+
variable.description = description
|
|
723
|
+
|
|
724
|
+
def delete_variables(self, *name: str, silent: bool = True):
|
|
725
|
+
"""删除变量成员
|
|
726
|
+
|
|
727
|
+
根据变量成员名列表删除多个变量
|
|
728
|
+
|
|
729
|
+
Args:
|
|
730
|
+
*name: 变量成员名
|
|
731
|
+
silent: 当变量不存在时,是报错还是静默处理。默认True, 即静默处理。
|
|
732
|
+
"""
|
|
733
|
+
not_exist = []
|
|
734
|
+
for n in name:
|
|
735
|
+
if n in self._gv_memo:
|
|
736
|
+
del self._gv_memo[n]
|
|
737
|
+
elif n in self._uv_memo:
|
|
738
|
+
del self._uv_memo[n]
|
|
739
|
+
else:
|
|
740
|
+
not_exist.append(n)
|
|
741
|
+
if not_exist and not silent:
|
|
742
|
+
raise VariableUpdateError(f"Variable: {not_exist} not exist.")
|
|
743
|
+
|
|
744
|
+
def __contains__(self, item):
|
|
745
|
+
return item in self._group.keys()
|
|
746
|
+
|
|
747
|
+
def __len__(self):
|
|
748
|
+
return len(self._group.keys())
|
|
749
|
+
|
|
750
|
+
|
|
751
|
+
class Variable(AsyncVariable, metaclass=SyncMeta):
|
|
752
|
+
synchronize = ('save', )
|
|
753
|
+
|
|
754
|
+
if TYPE_CHECKING: # pragma: no cover
|
|
755
|
+
def save(self):
|
|
756
|
+
...
|