deepfos 1.1.23__tar.gz → 1.1.26__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.
- {deepfos-1.1.23 → deepfos-1.1.26}/PKG-INFO +1 -1
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/_version.py +3 -3
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/journal_model.py +10 -1
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/models/financial_model.py +8 -4
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/element/finmodel.py +235 -30
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/element/journal.py +250 -101
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/exceptions/__init__.py +4 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/lib/asynchronous.py +50 -23
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/lib/discovery.py +4 -1
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/lib/serutils.py +4 -20
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos.egg-info/PKG-INFO +1 -1
- {deepfos-1.1.23 → deepfos-1.1.26}/MANIFEST.in +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/README.md +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/__init__.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/algo/__init__.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/algo/graph.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/V1_1/__init__.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/V1_1/business_model.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/V1_1/dimension.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/V1_1/models/__init__.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/V1_1/models/business_model.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/V1_1/models/dimension.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/V1_2/__init__.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/V1_2/dimension.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/V1_2/models/__init__.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/V1_2/models/dimension.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/__init__.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/account.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/accounting_engines.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/app.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/approval_process.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/base.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/business_model.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/consolidation.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/consolidation_process.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/datatable.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/deepconnector.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/deepfos_task.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/deepmodel.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/dimension.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/financial_model.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/journal_template.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/memory_financial_model.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/models/__init__.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/models/account.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/models/accounting_engines.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/models/app.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/models/approval_process.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/models/base.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/models/business_model.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/models/consolidation.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/models/consolidation_process.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/models/datatable_mysql.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/models/deepconnector.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/models/deepfos_task.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/models/deepmodel.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/models/dimension.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/models/journal_model.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/models/journal_template.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/models/memory_financial_model.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/models/platform.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/models/python.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/models/reconciliation_engine.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/models/reconciliation_report.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/models/role_strategy.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/models/smartlist.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/models/space.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/models/system.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/models/variable.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/models/workflow.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/platform.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/python.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/reconciliation_engine.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/reconciliation_report.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/role_strategy.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/smartlist.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/space.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/system.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/variable.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/api/workflow.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/boost/__init__.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/boost/jstream.c +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/boost/jstream.pyx +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/boost/pandas.c +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/boost/pandas.pyx +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/boost/py_jstream.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/boost/py_pandas.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/cache.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/config.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/core/__init__.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/core/cube/__init__.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/core/cube/_base.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/core/cube/constants.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/core/cube/cube.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/core/cube/formula.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/core/cube/syscube.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/core/cube/typing.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/core/cube/utils.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/core/dimension/__init__.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/core/dimension/_base.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/core/dimension/dimcreator.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/core/dimension/dimension.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/core/dimension/dimexpr.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/core/dimension/dimmember.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/core/dimension/eledimension.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/core/dimension/filters.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/core/dimension/sysdimension.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/core/logictable/__init__.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/core/logictable/_cache.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/core/logictable/_operator.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/core/logictable/nodemixin.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/core/logictable/sqlcondition.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/core/logictable/tablemodel.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/db/__init__.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/db/cipher.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/db/clickhouse.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/db/connector.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/db/daclickhouse.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/db/dameng.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/db/damysql.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/db/dbkits.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/db/deepengine.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/db/deepmodel.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/db/deepmodel_kingbase.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/db/edb.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/db/gauss.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/db/kingbase.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/db/mysql.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/db/oracle.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/db/postgresql.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/db/sqlserver.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/db/utils.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/element/__init__.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/element/accounting.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/element/apvlprocess.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/element/base.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/element/bizmodel.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/element/datatable.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/element/deepconnector.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/element/deepmodel.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/element/dimension.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/element/fact_table.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/element/journal_template.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/element/pyscript.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/element/reconciliation.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/element/rolestrategy.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/element/smartlist.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/element/variable.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/element/workflow.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/exceptions/hook.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/lazy.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/lib/__init__.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/lib/_javaobj.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/lib/concurrency.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/lib/constant.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/lib/decorator.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/lib/deepchart.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/lib/deepux.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/lib/eureka.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/lib/filterparser.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/lib/httpcli.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/lib/jsonstreamer.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/lib/nacos.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/lib/patch.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/lib/redis.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/lib/stopwatch.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/lib/subtask.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/lib/sysutils.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/lib/utils.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/local.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/options.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos/translation.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos.egg-info/SOURCES.txt +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos.egg-info/dependency_links.txt +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos.egg-info/not-zip-safe +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos.egg-info/requires.txt +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/deepfos.egg-info/top_level.txt +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/setup.cfg +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/setup.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/tests/__init__.py +0 -0
- {deepfos-1.1.23 → deepfos-1.1.26}/versioneer.py +0 -0
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2023-
|
|
11
|
+
"date": "2023-12-28T02:24:37+0000",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "1.1.
|
|
14
|
+
"full-revisionid": "7b2975015e7105274b4054e1136a0dfc22361966",
|
|
15
|
+
"version": "1.1.26"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -30,7 +30,16 @@ class JournalModelData(ChildAPI):
|
|
|
30
30
|
基于凭证模型的数据批量保存
|
|
31
31
|
"""
|
|
32
32
|
return {'body': batch}
|
|
33
|
-
|
|
33
|
+
|
|
34
|
+
@post('/data/update')
|
|
35
|
+
def update(self, batch: ModelDataBatchDTO) -> Union[CommonResultDTO, Awaitable[CommonResultDTO]]:
|
|
36
|
+
"""
|
|
37
|
+
【★】凭证模型-数据-单条更新-只支持头行更新及行插入和删除
|
|
38
|
+
|
|
39
|
+
基于凭证模型的数据更新
|
|
40
|
+
"""
|
|
41
|
+
return {'body': batch}
|
|
42
|
+
|
|
34
43
|
@post('data/calc/net/amount')
|
|
35
44
|
def calc_net_amount(self, param: JmPostParamVO) -> Union[JmPostResultVO, Awaitable[JmPostResultVO]]:
|
|
36
45
|
"""
|
|
@@ -187,14 +187,16 @@ class TaskExecutionResult(BaseModel):
|
|
|
187
187
|
|
|
188
188
|
- **POST** ``/mdx/task/execution`` (Response: 200)
|
|
189
189
|
"""
|
|
190
|
-
#:
|
|
190
|
+
#: 业务id
|
|
191
191
|
businessId: Optional[str]
|
|
192
|
-
#:
|
|
192
|
+
#: 失败原因
|
|
193
193
|
failReason: Optional[str]
|
|
194
|
-
#:
|
|
194
|
+
#: 处理是否正常,true 正常, false 异常
|
|
195
195
|
result: Optional[bool]
|
|
196
|
-
#: status
|
|
196
|
+
#: 状态,默认为0(正常返回),超时为1(超时返回),判断超时逻辑:result = true & status = 1
|
|
197
197
|
status: Optional[int]
|
|
198
|
+
#: 计算脚本影响单元格数,模型编辑器入口时返回具体值,其他时候返回null
|
|
199
|
+
cell: Optional[int]
|
|
198
200
|
|
|
199
201
|
|
|
200
202
|
class CubeRightElementDTO(BaseModel):
|
|
@@ -1157,6 +1159,8 @@ class ReactSpreadsheetSaveForm(BaseModel):
|
|
|
1157
1159
|
wbName: Optional[str]
|
|
1158
1160
|
#: 电子表格path
|
|
1159
1161
|
wbPath: Optional[str]
|
|
1162
|
+
#: 是否回调
|
|
1163
|
+
callback: Optional[bool]
|
|
1160
1164
|
|
|
1161
1165
|
|
|
1162
1166
|
class SheetColumnDto(BaseModel):
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import asyncio
|
|
2
2
|
import re
|
|
3
3
|
from enum import Enum
|
|
4
|
+
from itertools import chain
|
|
4
5
|
from typing import (
|
|
5
|
-
List, Dict, Optional, Union,
|
|
6
|
-
Tuple, Iterable, TYPE_CHECKING, Any
|
|
6
|
+
List, Dict, Optional, Union,
|
|
7
|
+
Tuple, Iterable, TYPE_CHECKING, Any, Set
|
|
7
8
|
)
|
|
9
|
+
|
|
10
|
+
import numpy as np
|
|
8
11
|
import pandas as pd
|
|
9
12
|
from pydantic import Field, parse_obj_as
|
|
10
13
|
from loguru import logger
|
|
@@ -24,7 +27,7 @@ from deepfos.lib.utils import (
|
|
|
24
27
|
dict_to_sql, split_dataframe, find_str, concat_url, CIEnumMeta
|
|
25
28
|
)
|
|
26
29
|
from deepfos.lib.constant import (
|
|
27
|
-
DFLT_DATA_COLUMN, VIEW, VIEW_DICT,
|
|
30
|
+
DFLT_DATA_COLUMN, VIEW, VIEW_DICT,
|
|
28
31
|
HIERARCHY, DECIMAL_COL, STRING_COL
|
|
29
32
|
)
|
|
30
33
|
from deepfos.boost import pandas as bp
|
|
@@ -41,8 +44,7 @@ from deepfos.api.models.financial_model import (
|
|
|
41
44
|
from deepfos.api.models.base import BaseModel
|
|
42
45
|
from deepfos.options import OPTION
|
|
43
46
|
from deepfos.lib.decorator import cached_property
|
|
44
|
-
from deepfos.exceptions import MDXExecuteTimeout
|
|
45
|
-
|
|
47
|
+
from deepfos.exceptions import MDXExecuteTimeout, MDXExecuteFail
|
|
46
48
|
|
|
47
49
|
__all__ = [
|
|
48
50
|
'AsyncFinancialCube',
|
|
@@ -110,6 +112,16 @@ class RoundType(int, Enum, metaclass=CIEnumMeta):
|
|
|
110
112
|
|
|
111
113
|
_RE_USE_SECTION = re.compile(r'.*USE\s+\w+;', re.I | re.S)
|
|
112
114
|
|
|
115
|
+
# 可直接转为mdx member或简单集合函数方法的维度表达式
|
|
116
|
+
# 维度名由字母数字下划线和中划线组成,或者等于#root
|
|
117
|
+
_RE_SIMPLE_EXPR = re.compile(
|
|
118
|
+
r'(?P<hierarchy>i?(base|descendant|children))'
|
|
119
|
+
r'\s*\((?P<mbr>(\x23root)|([\w\.\-\[\]]+))\s*,'
|
|
120
|
+
r'\s*[01]\s*(,\s*(?P<with_parent>[01])\s*)?\)',
|
|
121
|
+
re.I
|
|
122
|
+
)
|
|
123
|
+
RE_NAME_WITH_PARENT = re.compile(r'\[(.+)]\.\[(.+)]')
|
|
124
|
+
|
|
113
125
|
|
|
114
126
|
# -----------------------------------------------------------------------------
|
|
115
127
|
# core classes
|
|
@@ -195,6 +207,12 @@ class AsyncFinancialCube(ElementBase[FinancialModelAPI]):
|
|
|
195
207
|
|
|
196
208
|
return dim_memo
|
|
197
209
|
|
|
210
|
+
@cached_property
|
|
211
|
+
def account_col(self) -> str:
|
|
212
|
+
for dim in self._meta.cubeDimensionList:
|
|
213
|
+
if dim.dimensionUsage == 4:
|
|
214
|
+
return dim.datatableColumn
|
|
215
|
+
|
|
198
216
|
@cached_property
|
|
199
217
|
def dim_elements(self) -> LazyDict[str, AsyncDimension]:
|
|
200
218
|
"""财务Cube的维度元素
|
|
@@ -355,7 +373,8 @@ class AsyncFinancialCube(ElementBase[FinancialModelAPI]):
|
|
|
355
373
|
pivot_dim: Optional[str] = None,
|
|
356
374
|
validate_expr: bool = True,
|
|
357
375
|
verify_access: bool = False,
|
|
358
|
-
include_ignored: bool = False
|
|
376
|
+
include_ignored: bool = False,
|
|
377
|
+
normalize_view: bool = False,
|
|
359
378
|
) -> Union[pd.DataFrame, Tuple[pd.DataFrame, Dict[str, str]]]:
|
|
360
379
|
"""
|
|
361
380
|
根据维度表达式以及pov获取cube数据
|
|
@@ -368,6 +387,7 @@ class AsyncFinancialCube(ElementBase[FinancialModelAPI]):
|
|
|
368
387
|
validate_expr: 是否需要python校验/修改表达式,开启可能会导致额外的接口请求
|
|
369
388
|
verify_access: 是否带权限查询
|
|
370
389
|
include_ignored: 包含多版本实体维时,是否在结果中包含无效数据(即i列为1的数据)
|
|
390
|
+
normalize_view: 是否把大小写View统一成"View"
|
|
371
391
|
|
|
372
392
|
.. admonition:: 示例
|
|
373
393
|
|
|
@@ -425,6 +445,13 @@ class AsyncFinancialCube(ElementBase[FinancialModelAPI]):
|
|
|
425
445
|
data = pd.DataFrame(columns=columns)
|
|
426
446
|
data[DFLT_DATA_COLUMN] = data[DFLT_DATA_COLUMN].astype(float)
|
|
427
447
|
|
|
448
|
+
if normalize_view:
|
|
449
|
+
if (view := VIEW.lower()) in data.columns:
|
|
450
|
+
if VIEW in data.columns:
|
|
451
|
+
data[view] = np.where(data[VIEW].isnull(), data[view], data[VIEW])
|
|
452
|
+
data = data.drop(columns=[VIEW])
|
|
453
|
+
data = data.rename(columns=VIEW_DICT)
|
|
454
|
+
|
|
428
455
|
if pivot_dim is not None:
|
|
429
456
|
pivot_col = self._get_column_from_dim(pivot_dim)
|
|
430
457
|
|
|
@@ -459,6 +486,7 @@ class AsyncFinancialCube(ElementBase[FinancialModelAPI]):
|
|
|
459
486
|
need_check: bool = True,
|
|
460
487
|
data_audit: bool = True,
|
|
461
488
|
chunksize: Optional[int] = None,
|
|
489
|
+
callback: bool = True
|
|
462
490
|
):
|
|
463
491
|
"""
|
|
464
492
|
将DataFrame的数据保存至cube。
|
|
@@ -471,6 +499,7 @@ class AsyncFinancialCube(ElementBase[FinancialModelAPI]):
|
|
|
471
499
|
data_audit: 是否需要记录到数据审计
|
|
472
500
|
chunksize: 单次调用保存接口时最大的dataframe行数。
|
|
473
501
|
当data的行数超过此值时,将会分多次进行保存。
|
|
502
|
+
callback: 是否回调
|
|
474
503
|
|
|
475
504
|
Note:
|
|
476
505
|
此方法会对落库数据做以下处理:
|
|
@@ -511,7 +540,10 @@ class AsyncFinancialCube(ElementBase[FinancialModelAPI]):
|
|
|
511
540
|
if missing_dims := required_cols - set(data.columns):
|
|
512
541
|
raise ValueError(
|
|
513
542
|
f"Cannot save data because following columns are missing: {missing_dims}")
|
|
514
|
-
return await self._save_impl(
|
|
543
|
+
return await self._save_impl(
|
|
544
|
+
data[list(required_cols)],
|
|
545
|
+
pov, need_check, data_audit, chunksize, callback
|
|
546
|
+
)
|
|
515
547
|
|
|
516
548
|
async def save_unpivot(
|
|
517
549
|
self,
|
|
@@ -522,6 +554,7 @@ class AsyncFinancialCube(ElementBase[FinancialModelAPI]):
|
|
|
522
554
|
data_audit: bool = True,
|
|
523
555
|
chunksize: Optional[int] = None,
|
|
524
556
|
save_nan: bool = False,
|
|
557
|
+
callback: bool = True
|
|
525
558
|
):
|
|
526
559
|
"""保存有某个维度所有成员在列上的 ``DataFrame``
|
|
527
560
|
|
|
@@ -539,6 +572,7 @@ class AsyncFinancialCube(ElementBase[FinancialModelAPI]):
|
|
|
539
572
|
chunksize: 单次调用保存接口时最大的dataframe行数。
|
|
540
573
|
当data的行数超过此值时,将会分多次进行保存。
|
|
541
574
|
save_nan: 当把数据列成员转换到行上时,data为空的数据是否保存
|
|
575
|
+
callback: 是否回调
|
|
542
576
|
|
|
543
577
|
Warnings:
|
|
544
578
|
由于数据完整性等原因,此方法接收的dataframe数据列经常会有一些额外的空值。
|
|
@@ -582,7 +616,9 @@ class AsyncFinancialCube(ElementBase[FinancialModelAPI]):
|
|
|
582
616
|
logger.info("Will not save to cube because dataframe is empty.")
|
|
583
617
|
return
|
|
584
618
|
|
|
585
|
-
return await self._save_impl(
|
|
619
|
+
return await self._save_impl(
|
|
620
|
+
data, pov, need_check, data_audit, chunksize, callback
|
|
621
|
+
)
|
|
586
622
|
|
|
587
623
|
async def _save_impl(
|
|
588
624
|
self,
|
|
@@ -591,6 +627,7 @@ class AsyncFinancialCube(ElementBase[FinancialModelAPI]):
|
|
|
591
627
|
need_check: bool = True,
|
|
592
628
|
data_audit: bool = True,
|
|
593
629
|
chunksize: Optional[int] = None,
|
|
630
|
+
callback: bool = True
|
|
594
631
|
):
|
|
595
632
|
# replace NaN to standard None
|
|
596
633
|
data = data.mask(data.isna(), None)
|
|
@@ -615,16 +652,144 @@ class AsyncFinancialCube(ElementBase[FinancialModelAPI]):
|
|
|
615
652
|
needCheck=need_check,
|
|
616
653
|
dataAuditSwitch=data_audit,
|
|
617
654
|
entryMode=1,
|
|
618
|
-
validateDimensionMember=need_check
|
|
655
|
+
validateDimensionMember=need_check,
|
|
656
|
+
callback=callback
|
|
657
|
+
)
|
|
658
|
+
r = await self.async_api.reactspreadsheet.save(
|
|
659
|
+
payload.dict(exclude_unset=True)
|
|
619
660
|
)
|
|
620
|
-
r = await self.async_api.reactspreadsheet.save(payload.dict(exclude_unset=True))
|
|
621
661
|
resp.append(r)
|
|
622
662
|
return resp
|
|
623
663
|
|
|
664
|
+
async def delete_with_mdx(
|
|
665
|
+
self,
|
|
666
|
+
expression: Union[str, Dict[str, Union[List[str], str]]]
|
|
667
|
+
):
|
|
668
|
+
"""通过MDX脚本删除数据
|
|
669
|
+
|
|
670
|
+
根据维度表达式删除Cube数据
|
|
671
|
+
|
|
672
|
+
Warnings:
|
|
673
|
+
此方法将根据维度表达式生成对应的MDX脚本并执行MDX的Cleardata
|
|
674
|
+
对于只有成员和单集合方法的表达式,可以直接转换为MDX的成员集合或集合函数表达式
|
|
675
|
+
如为复杂表达式(例如包含聚合方法),则会查询实际对应的成员后,再组成MDX的成员集合
|
|
676
|
+
|
|
677
|
+
Args:
|
|
678
|
+
expression: 维度表达式
|
|
679
|
+
|
|
680
|
+
.. admonition:: 示例
|
|
681
|
+
|
|
682
|
+
两种调用方式等价:
|
|
683
|
+
|
|
684
|
+
.. code-block:: python
|
|
685
|
+
:emphasize-lines: 3,8
|
|
686
|
+
|
|
687
|
+
cube = FinancialCube('example')
|
|
688
|
+
expr = 'Year{2021;2022}->Entiy{Base(TotalEntity,0)}'
|
|
689
|
+
r = cube.delete_with_mdx(expr)
|
|
690
|
+
expr_dict = {
|
|
691
|
+
"Year": ['2021', '2022'],
|
|
692
|
+
"Entity": "Base(TotalEntity,0)"
|
|
693
|
+
}
|
|
694
|
+
r = cube.delete_with_mdx(expr_dict)
|
|
695
|
+
|
|
696
|
+
Returns:
|
|
697
|
+
MDX执行结果
|
|
698
|
+
|
|
699
|
+
See Also:
|
|
700
|
+
:meth:`insert_null` :meth:`delete`
|
|
701
|
+
|
|
702
|
+
"""
|
|
703
|
+
if isinstance(expression, dict):
|
|
704
|
+
expression = dict_to_expr(expression)
|
|
705
|
+
|
|
706
|
+
query_dims = []
|
|
707
|
+
all_cols = set(self.dim_col_map.values())
|
|
708
|
+
dimexprs = {}
|
|
709
|
+
cols_appeared = set()
|
|
710
|
+
|
|
711
|
+
def normalize_name(name_: str) -> str:
|
|
712
|
+
if RE_NAME_WITH_PARENT.match(name_):
|
|
713
|
+
return name_
|
|
714
|
+
return f'[{name_}]'
|
|
715
|
+
|
|
716
|
+
async def query_dim(
|
|
717
|
+
col_: str,
|
|
718
|
+
part_: str,
|
|
719
|
+
dim_name_: str
|
|
720
|
+
) -> Tuple[str, Set[str]]:
|
|
721
|
+
result: List[Dict[str, Any]] = await self.dim_elements[dim_name_].query(
|
|
722
|
+
part_, fields=['name'], as_model=False
|
|
723
|
+
)
|
|
724
|
+
mbrs_ = set()
|
|
725
|
+
for item in result:
|
|
726
|
+
if (name := item.get('expectedName')) is not None:
|
|
727
|
+
mbrs_.add(f"[{col_}].{normalize_name(name)}")
|
|
728
|
+
else:
|
|
729
|
+
mbrs_.add(f"[{col_}].{normalize_name(item['name'])}")
|
|
730
|
+
return col_, mbrs_
|
|
731
|
+
|
|
732
|
+
for expr in expression.split('->'):
|
|
733
|
+
dim, body = unpack_expr(expr)
|
|
734
|
+
col = self._get_column_from_dim(dim)
|
|
735
|
+
|
|
736
|
+
for part in body.split(';'):
|
|
737
|
+
part = part.replace(' ', '')
|
|
738
|
+
if not part:
|
|
739
|
+
continue
|
|
740
|
+
|
|
741
|
+
cols_appeared.add(col)
|
|
742
|
+
|
|
743
|
+
if is_valid_pov(part):
|
|
744
|
+
dimexprs.setdefault(col, set()).add(
|
|
745
|
+
f"[{col}].{normalize_name(part)}"
|
|
746
|
+
)
|
|
747
|
+
elif match := _RE_SIMPLE_EXPR.match(part):
|
|
748
|
+
mbr = match.group('mbr')
|
|
749
|
+
hier = match.group('hierarchy').capitalize()
|
|
750
|
+
with_parent = match.group('with_parent')
|
|
751
|
+
|
|
752
|
+
if with_parent == '1':
|
|
753
|
+
dimexprs.setdefault(col, set()).add(
|
|
754
|
+
f"{hier}([{col}].{normalize_name(mbr)},WITH_PARENT)"
|
|
755
|
+
)
|
|
756
|
+
else:
|
|
757
|
+
dimexprs.setdefault(col, set()).add(
|
|
758
|
+
f"{hier}([{col}].{normalize_name(mbr)})"
|
|
759
|
+
)
|
|
760
|
+
else:
|
|
761
|
+
dim_name = self.col_dim_map.get(col, col)
|
|
762
|
+
query_dims.append(query_dim(col, part, dim_name))
|
|
763
|
+
|
|
764
|
+
for col in all_cols - cols_appeared:
|
|
765
|
+
dimexprs[col] = {f"Base([{col}].[#root])"}
|
|
766
|
+
|
|
767
|
+
dim_mbrs = await asyncio.gather(*query_dims)
|
|
768
|
+
|
|
769
|
+
for col, mbrs in dim_mbrs:
|
|
770
|
+
dimexprs.setdefault(col, set())
|
|
771
|
+
dimexprs[col] = dimexprs[col].union(mbrs)
|
|
772
|
+
|
|
773
|
+
# ClearData方法的维度范围优先使用科目维度
|
|
774
|
+
if account_col := self.account_col:
|
|
775
|
+
clear_data_expr = dimexprs.pop(account_col)
|
|
776
|
+
scope_expr = chain(*dimexprs.values())
|
|
777
|
+
else:
|
|
778
|
+
expr_list = list(dimexprs.values())
|
|
779
|
+
clear_data_expr = expr_list[0]
|
|
780
|
+
scope_expr = chain(*expr_list[1::])
|
|
781
|
+
|
|
782
|
+
script = """Scope(%s);\nCleardata(%s);\nEnd Scope;
|
|
783
|
+
""" % (','.join(scope_expr), ','.join(clear_data_expr))
|
|
784
|
+
|
|
785
|
+
return await self.mdx_execution(script)
|
|
786
|
+
|
|
624
787
|
async def delete(
|
|
625
788
|
self,
|
|
626
789
|
expression: Union[str, Dict[str, Union[List[str], str]]],
|
|
627
|
-
chunksize: Optional[int] = None
|
|
790
|
+
chunksize: Optional[int] = None,
|
|
791
|
+
use_mdx: bool = False,
|
|
792
|
+
callback: bool = True
|
|
628
793
|
):
|
|
629
794
|
"""删除数据
|
|
630
795
|
|
|
@@ -639,6 +804,8 @@ class AsyncFinancialCube(ElementBase[FinancialModelAPI]):
|
|
|
639
804
|
expression: 维度表达式
|
|
640
805
|
chunksize: 单次调用保存接口时最大的dataframe行数。
|
|
641
806
|
当data的行数超过此值时,将会分多次进行保存。
|
|
807
|
+
use_mdx: 是否使用MDX脚本实现,默认为否,等效于调用 :meth:`delete_with_mdx`
|
|
808
|
+
callback: 是否回调
|
|
642
809
|
|
|
643
810
|
.. admonition:: 示例
|
|
644
811
|
|
|
@@ -660,26 +827,31 @@ class AsyncFinancialCube(ElementBase[FinancialModelAPI]):
|
|
|
660
827
|
删除结果
|
|
661
828
|
|
|
662
829
|
See Also:
|
|
663
|
-
:meth:`insert_null`
|
|
830
|
+
:meth:`insert_null` :meth:`delete_with_mdx`
|
|
664
831
|
|
|
665
832
|
"""
|
|
833
|
+
if use_mdx:
|
|
834
|
+
return await self.delete_with_mdx(expression)
|
|
835
|
+
|
|
666
836
|
if self._meta.autoCalculation:
|
|
667
837
|
if isinstance(expression, str):
|
|
668
838
|
expression = expr_to_dict(expression)
|
|
669
839
|
expression = {**expression}
|
|
670
|
-
# expression.pop(VIEW, None)
|
|
671
840
|
|
|
672
841
|
if isinstance(expression, dict):
|
|
673
842
|
expression = dict_to_expr(expression)
|
|
674
843
|
|
|
675
844
|
data, pov = await self.query(expression)
|
|
676
845
|
data[DFLT_DATA_COLUMN] = None
|
|
677
|
-
return await self.save(
|
|
846
|
+
return await self.save(
|
|
847
|
+
data, pov, data_audit=True, chunksize=chunksize, callback=callback
|
|
848
|
+
)
|
|
678
849
|
|
|
679
850
|
async def queries(
|
|
680
851
|
self,
|
|
681
852
|
expressions: Iterable[str],
|
|
682
|
-
drop_duplicates: bool = True
|
|
853
|
+
drop_duplicates: bool = True,
|
|
854
|
+
normalize_view: bool = False,
|
|
683
855
|
) -> pd.DataFrame:
|
|
684
856
|
"""查询多个表达式
|
|
685
857
|
|
|
@@ -689,20 +861,23 @@ class AsyncFinancialCube(ElementBase[FinancialModelAPI]):
|
|
|
689
861
|
Args:
|
|
690
862
|
expressions: 待查询的维度表达式列表
|
|
691
863
|
drop_duplicates: 是否需要去重
|
|
864
|
+
normalize_view: 是否把大小写View统一成"View"
|
|
692
865
|
|
|
693
866
|
Returns:
|
|
694
867
|
查询结果
|
|
695
868
|
|
|
696
869
|
"""
|
|
697
870
|
if isinstance(expressions, str):
|
|
698
|
-
return await self.query(
|
|
871
|
+
return await self.query(
|
|
872
|
+
expressions, compact=False, normalize_view=normalize_view)
|
|
699
873
|
|
|
700
874
|
expressions = list(expressions)
|
|
701
875
|
if len(expressions) == 1:
|
|
702
|
-
return await self.query(
|
|
876
|
+
return await self.query(
|
|
877
|
+
expressions[0], compact=False, normalize_view=normalize_view)
|
|
703
878
|
|
|
704
879
|
df_list = await asyncio.gather(*(
|
|
705
|
-
self.query(expr, compact=False)
|
|
880
|
+
self.query(expr, compact=False, normalize_view=True)
|
|
706
881
|
for expr in expressions
|
|
707
882
|
))
|
|
708
883
|
|
|
@@ -711,13 +886,12 @@ class AsyncFinancialCube(ElementBase[FinancialModelAPI]):
|
|
|
711
886
|
data = pd.DataFrame(columns=dflt_cols)
|
|
712
887
|
data[DFLT_DATA_COLUMN] = data[DFLT_DATA_COLUMN].astype(float)
|
|
713
888
|
else:
|
|
714
|
-
if self._meta.autoCalculation:
|
|
715
|
-
for idx in range(len(df_list)):
|
|
716
|
-
df_list[idx] = df_list[idx].rename(columns={VIEW: 'view'})
|
|
717
889
|
data = pd.concat(df_list, sort=False)
|
|
718
890
|
if drop_duplicates:
|
|
719
891
|
dim_cols = data.columns.difference([DFLT_DATA_COLUMN])
|
|
720
892
|
data = data.drop_duplicates(dim_cols)
|
|
893
|
+
if not normalize_view:
|
|
894
|
+
data = data.rename(columns={VIEW: "view"})
|
|
721
895
|
return data
|
|
722
896
|
|
|
723
897
|
async def pc_init(
|
|
@@ -995,7 +1169,7 @@ class AsyncFinancialCube(ElementBase[FinancialModelAPI]):
|
|
|
995
1169
|
script: str,
|
|
996
1170
|
parameters: Optional[Dict[str, str]] = None,
|
|
997
1171
|
precision: Optional[int] = None,
|
|
998
|
-
timeout: Optional[int] =
|
|
1172
|
+
timeout: Optional[int] = None,
|
|
999
1173
|
round_type: Union[RoundType, str] = RoundType.floor,
|
|
1000
1174
|
):
|
|
1001
1175
|
"""执行MDX计算语句
|
|
@@ -1047,10 +1221,18 @@ class AsyncFinancialCube(ElementBase[FinancialModelAPI]):
|
|
|
1047
1221
|
|
|
1048
1222
|
"""
|
|
1049
1223
|
if _RE_USE_SECTION.match(script.upper()):
|
|
1050
|
-
raise ValueError(
|
|
1224
|
+
raise ValueError(
|
|
1225
|
+
'MDX语句中发现use section,在FinancialCube中使用时,'
|
|
1226
|
+
'固定为当前Cube,不支持指定其他Cube'
|
|
1227
|
+
)
|
|
1228
|
+
|
|
1229
|
+
if timeout is None:
|
|
1230
|
+
timeout = OPTION.api.timeout * 1000
|
|
1051
1231
|
|
|
1052
|
-
business_id = (
|
|
1053
|
-
|
|
1232
|
+
business_id = (
|
|
1233
|
+
f"PythonScript_{OPTION.general.task_info.get('script_name', '')}_MDX"
|
|
1234
|
+
f"-{datetime.datetime.now().strftime('%Y%m%d_%H%M%S_%f')}"
|
|
1235
|
+
)
|
|
1054
1236
|
params = []
|
|
1055
1237
|
|
|
1056
1238
|
if parameters is not None:
|
|
@@ -1063,12 +1245,17 @@ class AsyncFinancialCube(ElementBase[FinancialModelAPI]):
|
|
|
1063
1245
|
path = self._path
|
|
1064
1246
|
|
|
1065
1247
|
if path is None:
|
|
1066
|
-
path = await AppAPI(sync=False).folder.get_folder_full(
|
|
1248
|
+
path = await AppAPI(sync=False).folder.get_folder_full(
|
|
1249
|
+
self.element_info.folderId
|
|
1250
|
+
)
|
|
1067
1251
|
|
|
1068
1252
|
path = path.replace('\\', '/')
|
|
1069
1253
|
|
|
1070
1254
|
params.append(
|
|
1071
|
-
MDXCubeParameter(
|
|
1255
|
+
MDXCubeParameter(
|
|
1256
|
+
key=self.element_name,
|
|
1257
|
+
value=concat_url(path, f"{self.element_name}.cub")
|
|
1258
|
+
)
|
|
1072
1259
|
)
|
|
1073
1260
|
|
|
1074
1261
|
res = await self.async_api.mdxtask.execution(
|
|
@@ -1085,6 +1272,11 @@ class AsyncFinancialCube(ElementBase[FinancialModelAPI]):
|
|
|
1085
1272
|
if res.status == 1:
|
|
1086
1273
|
raise MDXExecuteTimeout(f'MDX执行超时,具体响应:\n{res}')
|
|
1087
1274
|
|
|
1275
|
+
if res.result is False:
|
|
1276
|
+
raise MDXExecuteFail(
|
|
1277
|
+
f'MDX执行失败,失败原因:\n{res.failReason}'
|
|
1278
|
+
)
|
|
1279
|
+
|
|
1088
1280
|
return res
|
|
1089
1281
|
|
|
1090
1282
|
|
|
@@ -1095,6 +1287,7 @@ class FinancialCube(AsyncFinancialCube, metaclass=SyncMeta):
|
|
|
1095
1287
|
'save',
|
|
1096
1288
|
'save_unpivot',
|
|
1097
1289
|
'delete',
|
|
1290
|
+
'delete_with_mdx',
|
|
1098
1291
|
'pc_init',
|
|
1099
1292
|
'pc_update',
|
|
1100
1293
|
'pc_upsert',
|
|
@@ -1107,7 +1300,8 @@ class FinancialCube(AsyncFinancialCube, metaclass=SyncMeta):
|
|
|
1107
1300
|
def queries(
|
|
1108
1301
|
self,
|
|
1109
1302
|
expressions: Iterable[str],
|
|
1110
|
-
drop_duplicates: bool = True
|
|
1303
|
+
drop_duplicates: bool = True,
|
|
1304
|
+
normalize_view: bool = False,
|
|
1111
1305
|
) -> pd.DataFrame:
|
|
1112
1306
|
...
|
|
1113
1307
|
|
|
@@ -1119,7 +1313,8 @@ class FinancialCube(AsyncFinancialCube, metaclass=SyncMeta):
|
|
|
1119
1313
|
pivot_dim: Optional[str] = None,
|
|
1120
1314
|
validate_expr: bool = True,
|
|
1121
1315
|
verify_access: bool = False,
|
|
1122
|
-
include_ignored: bool = False
|
|
1316
|
+
include_ignored: bool = False,
|
|
1317
|
+
normalize_view: bool = False,
|
|
1123
1318
|
) -> Union[pd.DataFrame, Tuple[pd.DataFrame, Dict[str, str]]]:
|
|
1124
1319
|
...
|
|
1125
1320
|
|
|
@@ -1131,6 +1326,7 @@ class FinancialCube(AsyncFinancialCube, metaclass=SyncMeta):
|
|
|
1131
1326
|
need_check: bool = True,
|
|
1132
1327
|
data_audit: bool = True,
|
|
1133
1328
|
chunksize: Optional[int] = None,
|
|
1329
|
+
callback: bool = True
|
|
1134
1330
|
):
|
|
1135
1331
|
...
|
|
1136
1332
|
|
|
@@ -1143,13 +1339,22 @@ class FinancialCube(AsyncFinancialCube, metaclass=SyncMeta):
|
|
|
1143
1339
|
data_audit: bool = True,
|
|
1144
1340
|
chunksize: Optional[int] = None,
|
|
1145
1341
|
save_nan: bool = False,
|
|
1342
|
+
callback: bool = True
|
|
1146
1343
|
):
|
|
1147
1344
|
...
|
|
1148
1345
|
|
|
1149
1346
|
def delete(
|
|
1150
1347
|
self,
|
|
1151
1348
|
expression: Union[str, Dict[str, Union[List[str], str]]],
|
|
1152
|
-
chunksize: Optional[int] = None
|
|
1349
|
+
chunksize: Optional[int] = None,
|
|
1350
|
+
use_mdx: bool = False,
|
|
1351
|
+
callback: bool = True
|
|
1352
|
+
):
|
|
1353
|
+
...
|
|
1354
|
+
|
|
1355
|
+
def delete_with_mdx(
|
|
1356
|
+
self,
|
|
1357
|
+
expression: Union[str, Dict[str, Union[List[str], str]]]
|
|
1153
1358
|
):
|
|
1154
1359
|
...
|
|
1155
1360
|
|