deepfos 1.1.55__tar.gz → 1.1.56__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.55 → deepfos-1.1.56}/CHANGELOG.md +7 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/PKG-INFO +1 -1
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/_version.py +3 -3
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/element/deepmodel.py +8 -2
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/element/finmodel.py +123 -37
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/lib/sysutils.py +12 -6
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos.egg-info/PKG-INFO +1 -1
- {deepfos-1.1.55 → deepfos-1.1.56}/.gitattributes +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/.gitee/ISSUE_GUIDELINES.md +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/.gitee/ISSUE_TEMPLATE.md +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/.gitignore +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/MANIFEST.in +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/README.md +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/__init__.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/algo/__init__.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/algo/graph.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/V1_1/__init__.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/V1_1/business_model.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/V1_1/dimension.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/V1_1/models/__init__.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/V1_1/models/business_model.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/V1_1/models/dimension.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/V1_2/__init__.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/V1_2/dimension.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/V1_2/models/__init__.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/V1_2/models/dimension.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/__init__.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/account.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/accounting_engines.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/app.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/approval_process.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/base.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/business_model.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/consolidation.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/consolidation_process.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/datatable.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/deep_pipeline.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/deepconnector.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/deepfos_task.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/deepmodel.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/dimension.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/financial_model.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/journal_model.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/journal_template.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/memory_financial_model.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/models/__init__.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/models/account.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/models/accounting_engines.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/models/app.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/models/approval_process.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/models/base.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/models/business_model.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/models/consolidation.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/models/consolidation_process.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/models/datatable_mysql.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/models/deep_pipeline.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/models/deepconnector.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/models/deepfos_task.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/models/deepmodel.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/models/dimension.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/models/financial_model.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/models/journal_model.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/models/journal_template.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/models/memory_financial_model.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/models/platform.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/models/python.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/models/reconciliation_engine.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/models/reconciliation_report.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/models/role_strategy.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/models/smartlist.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/models/space.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/models/system.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/models/variable.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/models/workflow.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/platform.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/python.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/reconciliation_engine.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/reconciliation_report.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/role_strategy.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/smartlist.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/space.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/system.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/variable.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/api/workflow.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/boost/__init__.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/boost/jstream.c +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/boost/jstream.pyx +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/boost/pandas.c +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/boost/pandas.pyx +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/boost/py_jstream.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/boost/py_pandas.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/cache.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/config.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/core/__init__.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/core/cube/__init__.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/core/cube/_base.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/core/cube/constants.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/core/cube/cube.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/core/cube/formula.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/core/cube/syscube.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/core/cube/typing.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/core/cube/utils.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/core/dimension/__init__.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/core/dimension/_base.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/core/dimension/dimcreator.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/core/dimension/dimension.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/core/dimension/dimexpr.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/core/dimension/dimmember.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/core/dimension/eledimension.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/core/dimension/filters.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/core/dimension/sysdimension.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/core/logictable/__init__.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/core/logictable/_cache.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/core/logictable/_operator.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/core/logictable/nodemixin.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/core/logictable/sqlcondition.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/core/logictable/tablemodel.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/db/__init__.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/db/cipher.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/db/clickhouse.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/db/connector.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/db/daclickhouse.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/db/dameng.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/db/damysql.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/db/dbkits.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/db/deepengine.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/db/deepmodel.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/db/deepmodel_kingbase.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/db/edb.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/db/gauss.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/db/kingbase.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/db/mysql.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/db/oracle.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/db/postgresql.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/db/sqlserver.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/db/utils.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/element/__init__.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/element/accounting.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/element/apvlprocess.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/element/base.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/element/bizmodel.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/element/datatable.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/element/deep_pipeline.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/element/deepconnector.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/element/dimension.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/element/fact_table.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/element/journal.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/element/journal_template.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/element/pyscript.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/element/reconciliation.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/element/rolestrategy.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/element/smartlist.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/element/variable.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/element/workflow.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/exceptions/__init__.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/exceptions/hook.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/lazy.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/lib/__init__.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/lib/_javaobj.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/lib/asynchronous.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/lib/concurrency.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/lib/constant.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/lib/decorator.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/lib/deepchart.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/lib/deepux.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/lib/discovery.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/lib/edb_lexer.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/lib/eureka.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/lib/filterparser.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/lib/httpcli.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/lib/jsonstreamer.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/lib/msg.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/lib/nacos.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/lib/patch.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/lib/redis.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/lib/serutils.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/lib/stopwatch.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/lib/subtask.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/lib/utils.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/local.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/options.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos/translation.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos.egg-info/SOURCES.txt +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos.egg-info/dependency_links.txt +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos.egg-info/not-zip-safe +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos.egg-info/requires.txt +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/deepfos.egg-info/top_level.txt +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/requirements.txt +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/setup.cfg +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/setup.py +0 -0
- {deepfos-1.1.55 → deepfos-1.1.56}/versioneer.py +0 -0
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2025-04-
|
|
11
|
+
"date": "2025-04-28T08:53:07+0000",
|
|
12
12
|
"dirty": false,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "1.1.
|
|
14
|
+
"full-revisionid": "65654605edcd2831ed325b40b62f71c933313017",
|
|
15
|
+
"version": "1.1.56"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -774,8 +774,12 @@ class AsyncDeepModel(ElementBase[DeepModelAPI]):
|
|
|
774
774
|
"""DeepModel元素
|
|
775
775
|
|
|
776
776
|
Args:
|
|
777
|
-
direct_access:
|
|
777
|
+
direct_access: 是否使用直连模式,默认为True
|
|
778
|
+
会结合OPTION.edgedb.dsn是否有值决定是否使用直连模式,如无值,则仍为非直连模式
|
|
779
|
+
直连模式下,会使用edgedb-python库直连edgedb server,
|
|
780
|
+
否则会使用DeepModel组件API进行操作
|
|
778
781
|
pg_dsn: PG连接信息
|
|
782
|
+
|
|
779
783
|
"""
|
|
780
784
|
__mangle_docs__ = False
|
|
781
785
|
|
|
@@ -783,7 +787,9 @@ class AsyncDeepModel(ElementBase[DeepModelAPI]):
|
|
|
783
787
|
self._txn_ = ContextVar('QLTXN')
|
|
784
788
|
self.appmodule = f"app{OPTION.api.header['app']}"
|
|
785
789
|
self.spacemodule = f"space{OPTION.api.header['space']}"
|
|
786
|
-
self.direct_access = direct_access
|
|
790
|
+
self.direct_access = direct_access and bool(OPTION.edgedb.dsn)
|
|
791
|
+
if not self.direct_access:
|
|
792
|
+
logger.debug('当前DeepModel为非直连模式')
|
|
787
793
|
self.alias = AliasGenerator()
|
|
788
794
|
self.pg_dsn = pg_dsn
|
|
789
795
|
self._globals = {}
|
|
@@ -487,10 +487,10 @@ class AsyncFinancialCube(ElementBase[FinancialModelAPI]):
|
|
|
487
487
|
pov: Optional[Union[str, Dict[str, str]]] = None,
|
|
488
488
|
data_column: str = DFLT_DATA_COLUMN,
|
|
489
489
|
comment_column: str = DFLT_COMMENT_COLUMN,
|
|
490
|
-
) -> pd.DataFrame:
|
|
490
|
+
) -> Tuple[pd.DataFrame, Dict[str, str]]:
|
|
491
491
|
if data.empty:
|
|
492
492
|
logger.info("Will not save to cube because dataframe is empty.")
|
|
493
|
-
return pd.DataFrame()
|
|
493
|
+
return pd.DataFrame(), {}
|
|
494
494
|
|
|
495
495
|
if data_column not in data.columns:
|
|
496
496
|
raise ValueError(f"Missing data column: {data_column}.")
|
|
@@ -537,7 +537,7 @@ class AsyncFinancialCube(ElementBase[FinancialModelAPI]):
|
|
|
537
537
|
data = pd.concat([data, cmt_data])
|
|
538
538
|
required_cols.add(COLUMN_USAGE_FIELD)
|
|
539
539
|
|
|
540
|
-
return data[list(required_cols)]
|
|
540
|
+
return data[list(required_cols)], pov
|
|
541
541
|
|
|
542
542
|
async def save(
|
|
543
543
|
self,
|
|
@@ -580,11 +580,34 @@ class AsyncFinancialCube(ElementBase[FinancialModelAPI]):
|
|
|
580
580
|
:meth:`save_unpivot`
|
|
581
581
|
|
|
582
582
|
"""
|
|
583
|
-
data = self._build_dataframe_for_save(data, pov, data_column, comment_column)
|
|
583
|
+
data, pov = self._build_dataframe_for_save(data, pov, data_column, comment_column)
|
|
584
|
+
if data.empty:
|
|
585
|
+
return
|
|
586
|
+
|
|
584
587
|
return await self._save_impl(
|
|
585
588
|
data, pov, need_check, data_audit, chunksize, callback, auth_mode
|
|
586
589
|
)
|
|
587
590
|
|
|
591
|
+
def _complement(
|
|
592
|
+
self,
|
|
593
|
+
data: pd.DataFrame,
|
|
594
|
+
expression: str,
|
|
595
|
+
default_hierarchy: str = 'Base',
|
|
596
|
+
pov: Dict[str, str] = None,
|
|
597
|
+
):
|
|
598
|
+
if isinstance(expression, dict):
|
|
599
|
+
expression = dict_to_expr(expression)
|
|
600
|
+
expr, pov = self._split_expr(expression, pov or {}, default_hierarchy)
|
|
601
|
+
full_expr = {**expr_to_dict(expr), **pov}
|
|
602
|
+
folders = {col: dim.folderId for col, dim in self.dimensions.items()}
|
|
603
|
+
data_comp = complete_cartesian_product(
|
|
604
|
+
full_expr,
|
|
605
|
+
data,
|
|
606
|
+
folder_ids=folders,
|
|
607
|
+
col_dim_map=self.col_dim_map,
|
|
608
|
+
)
|
|
609
|
+
return data_comp
|
|
610
|
+
|
|
588
611
|
async def complement_save(
|
|
589
612
|
self,
|
|
590
613
|
data: pd.DataFrame,
|
|
@@ -619,22 +642,42 @@ class AsyncFinancialCube(ElementBase[FinancialModelAPI]):
|
|
|
619
642
|
**kwargs: 其他可传给:meth:`save`的参数
|
|
620
643
|
|
|
621
644
|
"""
|
|
622
|
-
data = self._build_dataframe_for_save(data, pov, data_column, comment_column)
|
|
645
|
+
data, pov = self._build_dataframe_for_save(data, pov, data_column, comment_column)
|
|
623
646
|
if data.empty:
|
|
624
647
|
return
|
|
625
648
|
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
expr, pov = self._split_expr(expression, pov or {}, default_hierarchy)
|
|
629
|
-
full_expr = {**expr_to_dict(expr), **pov}
|
|
649
|
+
data_comp = self._complement(data, expression, default_hierarchy, pov)
|
|
650
|
+
return await self._save_impl(data_comp, pov, **kwargs)
|
|
630
651
|
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
652
|
+
def _build_dataframe_for_save_unpivot(
|
|
653
|
+
self,
|
|
654
|
+
data: pd.DataFrame,
|
|
655
|
+
unpivot_dim: str,
|
|
656
|
+
pov: Optional[Union[str, Dict[str, str]]] = None,
|
|
657
|
+
save_nan: bool = False,
|
|
658
|
+
) -> Tuple[pd.DataFrame, Dict[str, str]]:
|
|
659
|
+
if data.empty:
|
|
660
|
+
logger.info("Will not save to cube because dataframe is empty.")
|
|
661
|
+
return pd.DataFrame(), {}
|
|
662
|
+
|
|
663
|
+
data = data.rename(columns=self._maybe_get_column_from_dim)
|
|
664
|
+
dim = self._get_column_from_dim(unpivot_dim)
|
|
665
|
+
pov = self._resolve_pov_as_dict(pov)
|
|
666
|
+
data_cols = set(data.columns)
|
|
667
|
+
unpivot_cols = data_cols.difference(pov.keys(), self.dim_col_map.values())
|
|
668
|
+
if self._meta.autoCalculation:
|
|
669
|
+
unpivot_cols.discard(VIEW)
|
|
670
|
+
id_cols = data_cols - unpivot_cols
|
|
671
|
+
data = data.melt(
|
|
672
|
+
id_vars=id_cols, value_vars=unpivot_cols,
|
|
673
|
+
var_name=dim, value_name=DFLT_DATA_COLUMN
|
|
636
674
|
)
|
|
637
|
-
|
|
675
|
+
if not save_nan:
|
|
676
|
+
data = data.dropna()
|
|
677
|
+
if data.empty:
|
|
678
|
+
logger.info("Will not save to cube because dataframe is empty.")
|
|
679
|
+
return pd.DataFrame(), {}
|
|
680
|
+
return data, pov
|
|
638
681
|
|
|
639
682
|
async def save_unpivot(
|
|
640
683
|
self,
|
|
@@ -682,34 +725,62 @@ class AsyncFinancialCube(ElementBase[FinancialModelAPI]):
|
|
|
682
725
|
| :meth:`save`
|
|
683
726
|
|
|
684
727
|
"""
|
|
728
|
+
data, pov = self._build_dataframe_for_save_unpivot(
|
|
729
|
+
data, unpivot_dim, pov, save_nan
|
|
730
|
+
)
|
|
685
731
|
if data.empty:
|
|
686
|
-
logger.info("Will not save to cube because dataframe is empty.")
|
|
687
732
|
return
|
|
688
733
|
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
data_cols = set(data.columns)
|
|
693
|
-
unpivot_cols = data_cols.difference(pov.keys(), self.dim_col_map.values())
|
|
734
|
+
return await self._save_impl(
|
|
735
|
+
data, pov, need_check, data_audit, chunksize, callback
|
|
736
|
+
)
|
|
694
737
|
|
|
695
|
-
|
|
696
|
-
|
|
738
|
+
async def complement_save_unpivot(
|
|
739
|
+
self,
|
|
740
|
+
data: pd.DataFrame,
|
|
741
|
+
unpivot_dim: str,
|
|
742
|
+
expression: Union[str, Dict[str, Union[List[str], str]]],
|
|
743
|
+
default_hierarchy: str = "Base",
|
|
744
|
+
pov: Optional[Union[str, Dict[str, str]]] = None,
|
|
745
|
+
save_nan: bool = False,
|
|
746
|
+
**kwargs
|
|
747
|
+
):
|
|
748
|
+
"""覆盖指定维度范围并保有某个维度所有成员在列上的 ``DataFrame``
|
|
697
749
|
|
|
698
|
-
|
|
699
|
-
data
|
|
700
|
-
id_vars=id_cols, value_vars=unpivot_cols,
|
|
701
|
-
var_name=dim, value_name=DFLT_DATA_COLUMN
|
|
702
|
-
)
|
|
750
|
+
相比于:meth:`save_unpivot`,在保存前,会将`data`按照`expression`补全笛卡尔积。
|
|
751
|
+
并且不在`data`范围的数据以`None`填充
|
|
703
752
|
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
if data.empty:
|
|
707
|
-
logger.info("Will not save to cube because dataframe is empty.")
|
|
708
|
-
return
|
|
753
|
+
Note:
|
|
754
|
+
逻辑上等价于两次调用
|
|
709
755
|
|
|
710
|
-
|
|
711
|
-
|
|
756
|
+
.. code-block:: python
|
|
757
|
+
|
|
758
|
+
cube.delete(expression)
|
|
759
|
+
cube.save_unpivot(data, unpivot_dim, **kwargs)
|
|
760
|
+
|
|
761
|
+
Args:
|
|
762
|
+
data: 需要保存的数据
|
|
763
|
+
unpivot_dim: 成员在列上的维度
|
|
764
|
+
expression: 需要覆盖的范围(维度表达式)
|
|
765
|
+
default_hierarchy: 单expression中没指定对应维度时,默认取的层级函数,
|
|
766
|
+
即填充为 `default_hierarchy(#root,0)`
|
|
767
|
+
pov: Point Of View,维度表达式或者KV键值对格式。
|
|
768
|
+
need_check: 是否需要java接口校验脏数据
|
|
769
|
+
data_audit: 是否需要记录到数据审计
|
|
770
|
+
chunksize: 单次调用保存接口时最大的dataframe行数。
|
|
771
|
+
当data的行数超过此值时,将会分多次进行保存。
|
|
772
|
+
save_nan: 当把数据列成员转换到行上时,data为空的数据是否保存
|
|
773
|
+
callback: 是否回调
|
|
774
|
+
|
|
775
|
+
"""
|
|
776
|
+
data, pov = self._build_dataframe_for_save_unpivot(
|
|
777
|
+
data, unpivot_dim, pov, save_nan
|
|
712
778
|
)
|
|
779
|
+
if data.empty:
|
|
780
|
+
return
|
|
781
|
+
|
|
782
|
+
data_comp = self._complement(data, expression, default_hierarchy, pov)
|
|
783
|
+
return await self._save_impl(data_comp, pov, **kwargs)
|
|
713
784
|
|
|
714
785
|
async def _save_impl(
|
|
715
786
|
self,
|
|
@@ -722,7 +793,9 @@ class AsyncFinancialCube(ElementBase[FinancialModelAPI]):
|
|
|
722
793
|
auth_mode: Literal[0, 1, 2, 3] = 0,
|
|
723
794
|
):
|
|
724
795
|
# replace NaN to standard None
|
|
725
|
-
|
|
796
|
+
# NB: replace twice in case of infer None to nan happened in 2.x pandas
|
|
797
|
+
data = data.replace({None: np.nan})
|
|
798
|
+
data = data.replace({np.nan: None})
|
|
726
799
|
# ensure view is capitalized
|
|
727
800
|
if self._meta.autoCalculation:
|
|
728
801
|
data = data.rename(columns=VIEW_DICT)
|
|
@@ -1381,6 +1454,7 @@ class FinancialCube(AsyncFinancialCube, metaclass=SyncMeta):
|
|
|
1381
1454
|
'save',
|
|
1382
1455
|
'complement_save',
|
|
1383
1456
|
'save_unpivot',
|
|
1457
|
+
'complement_save_unpivot',
|
|
1384
1458
|
'delete',
|
|
1385
1459
|
'delete_with_mdx',
|
|
1386
1460
|
'pc_init',
|
|
@@ -1388,7 +1462,7 @@ class FinancialCube(AsyncFinancialCube, metaclass=SyncMeta):
|
|
|
1388
1462
|
'pc_upsert',
|
|
1389
1463
|
'insert_null',
|
|
1390
1464
|
'copy_calculate',
|
|
1391
|
-
'mdx_execution'
|
|
1465
|
+
'mdx_execution',
|
|
1392
1466
|
)
|
|
1393
1467
|
|
|
1394
1468
|
if TYPE_CHECKING: # pragma: no cover
|
|
@@ -1451,6 +1525,18 @@ class FinancialCube(AsyncFinancialCube, metaclass=SyncMeta):
|
|
|
1451
1525
|
):
|
|
1452
1526
|
...
|
|
1453
1527
|
|
|
1528
|
+
def complement_save_unpivot(
|
|
1529
|
+
self,
|
|
1530
|
+
data: pd.DataFrame,
|
|
1531
|
+
unpivot_dim: str,
|
|
1532
|
+
expression: Union[str, Dict[str, Union[List[str], str]]],
|
|
1533
|
+
default_hierarchy: str = "Base",
|
|
1534
|
+
pov: Optional[Union[str, Dict[str, str]]] = None,
|
|
1535
|
+
save_nan: bool = False,
|
|
1536
|
+
**kwargs
|
|
1537
|
+
):
|
|
1538
|
+
...
|
|
1539
|
+
|
|
1454
1540
|
def delete(
|
|
1455
1541
|
self,
|
|
1456
1542
|
expression: Union[str, Dict[str, Union[List[str], str]]],
|
|
@@ -105,6 +105,7 @@ def complete_cartesian_product(
|
|
|
105
105
|
df: pd.DataFrame = None,
|
|
106
106
|
paths: Union[str, Dict[str, str]] = None,
|
|
107
107
|
folder_ids: Union[str, Dict[str, str]] = None,
|
|
108
|
+
col_dim_map: Dict[str, str] = None,
|
|
108
109
|
) -> pd.DataFrame:
|
|
109
110
|
"""
|
|
110
111
|
构造完整的维度成员笛卡尔积
|
|
@@ -115,6 +116,7 @@ def complete_cartesian_product(
|
|
|
115
116
|
paths: fix中维度的path,如果所有维度的目录相同,传同一个path,否则传字典,key为维度名,value为path。
|
|
116
117
|
如果不传,则自动寻找维度对应的path。
|
|
117
118
|
folder_ids: 类似paths, 但值是folder_id
|
|
119
|
+
col_dim_map: data中的列名与实际维度名的映射关系,默认data中的列名与维度名相同
|
|
118
120
|
|
|
119
121
|
Returns:
|
|
120
122
|
维度成员笛卡尔积的DataFrame
|
|
@@ -165,29 +167,33 @@ def complete_cartesian_product(
|
|
|
165
167
|
else:
|
|
166
168
|
loc_key = "path"
|
|
167
169
|
loc_getter = lambda _: None
|
|
170
|
+
if col_dim_map is None:
|
|
171
|
+
col_dim_map = {}
|
|
168
172
|
|
|
169
173
|
# 遍历fix,如果fix的值为str,则认为是维度表达式,将表达式转换为成员list
|
|
170
174
|
mbrs = {}
|
|
171
175
|
futures = []
|
|
172
176
|
|
|
173
|
-
for
|
|
177
|
+
for col, exp in fix.items():
|
|
174
178
|
if isinstance(exp, str):
|
|
175
179
|
if "(" not in exp:
|
|
176
|
-
mbrs[
|
|
180
|
+
mbrs[col] = exp.split(';')
|
|
177
181
|
else:
|
|
182
|
+
dim = col_dim_map.get(col, col)
|
|
178
183
|
loc = loc_getter(dim)
|
|
179
184
|
future = evloop.apply(AsyncDimension(element_name=dim, **{loc_key: loc}).query(
|
|
180
185
|
expression=exp, fields=['name'], as_model=False
|
|
181
186
|
))
|
|
182
187
|
|
|
183
|
-
futures.append((
|
|
188
|
+
futures.append((col, future))
|
|
184
189
|
else:
|
|
185
190
|
if not isinstance(exp, list):
|
|
186
191
|
raise TypeError('fix参数的value只能为维度表达式(str)或维度成员(list)')
|
|
187
|
-
mbrs[
|
|
192
|
+
mbrs[col] = exp
|
|
188
193
|
|
|
189
|
-
for
|
|
190
|
-
|
|
194
|
+
for col, future in futures:
|
|
195
|
+
dim_mbrs = future.result()
|
|
196
|
+
mbrs[col] = [item['name'] for item in dim_mbrs]
|
|
191
197
|
|
|
192
198
|
if df is None:
|
|
193
199
|
df = pd.DataFrame(columns=list(fix.keys()))
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|