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
deepfos/db/utils.py
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import base64
|
|
3
|
+
|
|
4
|
+
from deepfos.api.python import PythonAPI
|
|
5
|
+
from deepfos.api.models.python import WorkerRegistry
|
|
6
|
+
|
|
7
|
+
from deepfos.lib.utils import retry, Wait
|
|
8
|
+
from deepfos.lib.constant import UNSET
|
|
9
|
+
from deepfos.lib.asynchronous import evloop
|
|
10
|
+
from deepfos.options import OPTION
|
|
11
|
+
from deepfos.exceptions import APIResponseError
|
|
12
|
+
from .cipher import AES
|
|
13
|
+
from deepfos.api.datatable import (MySQLAPI, ClickHouseAPI, SQLServerAPI, OracleAPI, KingBaseAPI,
|
|
14
|
+
GaussAPI, DaMengAPI, PostgreSQLAPI, DeepEngineAPI)
|
|
15
|
+
|
|
16
|
+
# -----------------------------------------------------------------------------
|
|
17
|
+
# constants
|
|
18
|
+
PENDING = 0
|
|
19
|
+
INITIALIZING = 1
|
|
20
|
+
INITIALIZED = 2
|
|
21
|
+
#: 账号失效时间
|
|
22
|
+
ACCOUNT_EXPIRE = 3600 * 8
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class DBConnecetionError(Exception):
|
|
26
|
+
pass
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class AbsLeaseManager:
|
|
30
|
+
DB = None
|
|
31
|
+
|
|
32
|
+
def __init__(self, interval):
|
|
33
|
+
self._last_renewal = None
|
|
34
|
+
self._interval = interval
|
|
35
|
+
self._task = UNSET
|
|
36
|
+
self._info = UNSET
|
|
37
|
+
self._renew_fn = None
|
|
38
|
+
|
|
39
|
+
async def new_api(self): # pragma: no cover
|
|
40
|
+
raise NotImplementedError
|
|
41
|
+
|
|
42
|
+
async def _try_renewal(self, api, raises=False):
|
|
43
|
+
try:
|
|
44
|
+
return True, await api.dml.create_account()
|
|
45
|
+
except APIResponseError as e:
|
|
46
|
+
if raises:
|
|
47
|
+
raise
|
|
48
|
+
py_api = await PythonAPI(version=2.0, sync=False)
|
|
49
|
+
await py_api.worker.register(WorkerRegistry(
|
|
50
|
+
hostname=OPTION.general.task_info['worker_name'],
|
|
51
|
+
db=[self.DB]
|
|
52
|
+
))
|
|
53
|
+
return False, e
|
|
54
|
+
|
|
55
|
+
@retry(wait=Wait(0.5, 'exp_backoff', 2), retries=4)
|
|
56
|
+
async def renew(self):
|
|
57
|
+
api = await self.new_api()
|
|
58
|
+
|
|
59
|
+
flag, account = await self._try_renewal(api)
|
|
60
|
+
if flag is False: # retry once
|
|
61
|
+
_, account = await self._try_renewal(api, raises=True)
|
|
62
|
+
|
|
63
|
+
self._info = account
|
|
64
|
+
return account
|
|
65
|
+
|
|
66
|
+
async def loop(self, slow_start=True):
|
|
67
|
+
if slow_start:
|
|
68
|
+
await asyncio.sleep(self._interval)
|
|
69
|
+
while True:
|
|
70
|
+
await self.renew()
|
|
71
|
+
await asyncio.sleep(self._interval)
|
|
72
|
+
|
|
73
|
+
def schedule(self, slow_start=True):
|
|
74
|
+
if self._task is UNSET:
|
|
75
|
+
try:
|
|
76
|
+
asyncio.get_running_loop()
|
|
77
|
+
self._task = asyncio.create_task(
|
|
78
|
+
self.loop(slow_start))
|
|
79
|
+
except RuntimeError:
|
|
80
|
+
self._task = evloop.create_task(
|
|
81
|
+
self.loop(slow_start))
|
|
82
|
+
|
|
83
|
+
def cancel(self):
|
|
84
|
+
if self._task is not UNSET:
|
|
85
|
+
self._task.cancel()
|
|
86
|
+
self._task = UNSET
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def decrypt(secret, cipher_text, encoding='utf8'):
|
|
90
|
+
return AES(secret).decrypt(
|
|
91
|
+
base64.b16decode(cipher_text)
|
|
92
|
+
).rstrip().decode(encoding)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def get_client_class(
|
|
96
|
+
element_type: str,
|
|
97
|
+
sync: bool = True
|
|
98
|
+
):
|
|
99
|
+
"""
|
|
100
|
+
根据元素类型获取对应的数据表元素类
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
element_type: 元素类型
|
|
104
|
+
sync: 同步或异步元素类,默认同步
|
|
105
|
+
|
|
106
|
+
"""
|
|
107
|
+
from deepfos.db import (MySQLClient, AsyncMySQLClient,
|
|
108
|
+
ClickHouseClient, AsyncClickHouseClient,
|
|
109
|
+
OracleClient, AsyncOracleClient,
|
|
110
|
+
SQLServerClient, AsyncSQLServerClient,
|
|
111
|
+
KingBaseClient, AsyncKingBaseClient,
|
|
112
|
+
GaussClient, AsyncGaussClient,
|
|
113
|
+
DaMengClient, AsyncDaMengClient,
|
|
114
|
+
PostgreSQLClient, AsyncPostgreSQLClient,
|
|
115
|
+
DeepEngineClient, AsyncDeepEngineClient)
|
|
116
|
+
if sync:
|
|
117
|
+
index = 0
|
|
118
|
+
else:
|
|
119
|
+
index = 1
|
|
120
|
+
cli = {
|
|
121
|
+
MySQLAPI.module_type: (MySQLClient, AsyncMySQLClient),
|
|
122
|
+
ClickHouseAPI.module_type: (ClickHouseClient, AsyncClickHouseClient),
|
|
123
|
+
SQLServerAPI.module_type: (SQLServerClient, AsyncSQLServerClient),
|
|
124
|
+
OracleAPI.module_type: (OracleClient, AsyncOracleClient),
|
|
125
|
+
KingBaseAPI.module_type: (KingBaseClient, AsyncKingBaseClient),
|
|
126
|
+
GaussAPI.module_type: (GaussClient, AsyncGaussClient),
|
|
127
|
+
DaMengAPI.module_type: (DaMengClient, AsyncDaMengClient),
|
|
128
|
+
PostgreSQLAPI.module_type: (PostgreSQLClient, AsyncPostgreSQLClient),
|
|
129
|
+
DeepEngineAPI.module_type: (DeepEngineClient, AsyncDeepEngineClient),
|
|
130
|
+
}.get(element_type.upper())
|
|
131
|
+
|
|
132
|
+
if cli is None:
|
|
133
|
+
raise TypeError(f"Unknown module type: {element_type}")
|
|
134
|
+
else:
|
|
135
|
+
return cli[index]
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
from typing import TYPE_CHECKING
|
|
2
|
+
|
|
3
|
+
from deepfos.lazy import lazify
|
|
4
|
+
|
|
5
|
+
if TYPE_CHECKING: # pragma: no cover
|
|
6
|
+
from .accounting import (
|
|
7
|
+
AccountingEngines, AsyncAccountingEngines,
|
|
8
|
+
BillEngines, AsyncBillEngines, CallbackInfo
|
|
9
|
+
)
|
|
10
|
+
from .apvlprocess import AsyncApprovalProcess, ApprovalProcess
|
|
11
|
+
from .bizmodel import BusinessModel, AsyncBusinessModel, CopyConfig
|
|
12
|
+
from .datatable import (
|
|
13
|
+
Datatable, AsyncDataTableMySQL, DataTableMySQL,
|
|
14
|
+
AsyncDataTableClickHouse, DataTableClickHouse,
|
|
15
|
+
AsyncDataTableOracle, DataTableOracle,
|
|
16
|
+
AsyncDataTableSQLServer, DataTableSQLServer,
|
|
17
|
+
AsyncDataTableKingBase, DataTableKingBase,
|
|
18
|
+
AsyncDataTableGauss, DataTableGauss,
|
|
19
|
+
AsyncDataTableDaMeng, DataTableDaMeng,
|
|
20
|
+
AsyncDataTablePostgreSQL, DataTablePostgreSQL,
|
|
21
|
+
AsyncDataTableDeepEngine, DataTableDeepEngine,
|
|
22
|
+
AsyncDataTableDeepModel, DataTableDeepModel,
|
|
23
|
+
AsyncDataTableDeepModelKingBase, DataTableDeepModelKingBase,
|
|
24
|
+
)
|
|
25
|
+
from .dimension import AsyncDimension, Dimension
|
|
26
|
+
from .fact_table import AsyncFactTable, FactTable
|
|
27
|
+
from .finmodel import AsyncFinancialCube, FinancialCube
|
|
28
|
+
from .journal_template import (
|
|
29
|
+
AsyncJournalTemplate, JournalTemplate, FullPostingParameter
|
|
30
|
+
)
|
|
31
|
+
from .rolestrategy import AsyncRoleStrategy, RoleStrategy
|
|
32
|
+
from .smartlist import AsyncSmartList, SmartList
|
|
33
|
+
from .variable import AsyncVariable, Variable
|
|
34
|
+
from .workflow import AsyncWorkFlow, WorkFlow
|
|
35
|
+
from .journal import AsyncJournalModel, JournalModel
|
|
36
|
+
from .deepmodel import AsyncDeepModel, DeepModel
|
|
37
|
+
from .deepconnector import AsyncDeepConnector, DeepConnector
|
|
38
|
+
from .deep_pipeline import AsyncDeepPipeline, DeepPipeline
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
lazify(
|
|
42
|
+
{
|
|
43
|
+
'deepfos.element.finmodel': (
|
|
44
|
+
'AsyncFinancialCube', 'FinancialCube'
|
|
45
|
+
),
|
|
46
|
+
'deepfos.element.accounting': (
|
|
47
|
+
'AccountingEngines', 'AsyncAccountingEngines',
|
|
48
|
+
'BillEngines', 'AsyncBillEngines', 'CallbackInfo'
|
|
49
|
+
),
|
|
50
|
+
'deepfos.element.apvlprocess': (
|
|
51
|
+
'AsyncApprovalProcess', 'ApprovalProcess'
|
|
52
|
+
),
|
|
53
|
+
'deepfos.element.bizmodel': (
|
|
54
|
+
'BusinessModel', 'AsyncBusinessModel', 'CopyConfig'
|
|
55
|
+
),
|
|
56
|
+
'deepfos.element.datatable': (
|
|
57
|
+
'Datatable',
|
|
58
|
+
'AsyncDataTableMySQL', 'DataTableMySQL',
|
|
59
|
+
'AsyncDataTableClickHouse', 'DataTableClickHouse',
|
|
60
|
+
'AsyncDataTableOracle', 'DataTableOracle',
|
|
61
|
+
'AsyncDataTableSQLServer', 'DataTableSQLServer',
|
|
62
|
+
'AsyncDataTableKingBase', 'DataTableKingBase',
|
|
63
|
+
'AsyncDataTableGauss', 'DataTableGauss',
|
|
64
|
+
'AsyncDataTableDaMeng', 'DataTableDaMeng',
|
|
65
|
+
'AsyncDataTablePostgreSQL', 'DataTablePostgreSQL',
|
|
66
|
+
'AsyncDataTableDeepEngine', 'DataTableDeepEngine',
|
|
67
|
+
'AsyncDataTableDeepModel', 'DataTableDeepModel',
|
|
68
|
+
'AsyncDataTableDeepModelKingBase', 'DataTableDeepModelKingBase',
|
|
69
|
+
),
|
|
70
|
+
'deepfos.element.dimension': ('AsyncDimension', 'Dimension'),
|
|
71
|
+
'deepfos.element.fact_table': ('AsyncFactTable', 'FactTable'),
|
|
72
|
+
'deepfos.element.journal_template': (
|
|
73
|
+
'AsyncJournalTemplate', 'JournalTemplate', 'FullPostingParameter'
|
|
74
|
+
),
|
|
75
|
+
'deepfos.element.rolestrategy': ('AsyncRoleStrategy', 'RoleStrategy'),
|
|
76
|
+
'deepfos.element.smartlist': ('AsyncSmartList', 'SmartList'),
|
|
77
|
+
'deepfos.element.variable': ('AsyncVariable', 'Variable'),
|
|
78
|
+
'deepfos.element.workflow': ('AsyncWorkFlow', 'WorkFlow'),
|
|
79
|
+
'deepfos.element.reconciliation': (
|
|
80
|
+
'AsyncReconciliationEngine', 'AsyncReconciliationMsEngine',
|
|
81
|
+
'ReconciliationEngine', 'ReconciliationMsEngine',
|
|
82
|
+
),
|
|
83
|
+
'deepfos.element.journal': ('AsyncJournalModel', 'JournalModel'),
|
|
84
|
+
'deepfos.element.deepmodel': ('AsyncDeepModel', 'DeepModel'),
|
|
85
|
+
'deepfos.element.deepconnector': ('AsyncDeepConnector', 'DeepConnector'),
|
|
86
|
+
'deepfos.element.deep_pipeline': ('AsyncDeepPipeline', 'DeepPipeline'),
|
|
87
|
+
},
|
|
88
|
+
globals()
|
|
89
|
+
)
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
from deepfos.lib.asynchronous import future_property
|
|
2
|
+
from typing import List, Dict, Union, TYPE_CHECKING
|
|
3
|
+
|
|
4
|
+
from deepfos.element.base import ElementBase, SyncMeta
|
|
5
|
+
from deepfos.api.accounting_engines import AccountingEnginesAPI, BillEnginesAPI, AccountingEventTypeAPI
|
|
6
|
+
from deepfos.lib.utils import CIEnum
|
|
7
|
+
from deepfos.api.models.accounting_engines import (
|
|
8
|
+
AccountingControlRequestDTO,
|
|
9
|
+
AccountingEnginesDTO,
|
|
10
|
+
AccountingEnginesRequestDTO,
|
|
11
|
+
DataDTO,
|
|
12
|
+
AccountingEnginesExecCallbackPythonDTO as CallbackInfo,
|
|
13
|
+
AccEventTypeTableDTO,
|
|
14
|
+
AccEventTypeElementDTO,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
__all__ = [
|
|
18
|
+
"AccountingEngines",
|
|
19
|
+
"AsyncAccountingEngines",
|
|
20
|
+
"BillEngines",
|
|
21
|
+
"AsyncBillEngines",
|
|
22
|
+
"CallbackInfo"
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
DEFAULT_CALLBACK_PARAMS = {"controlTableInfo", "success", "batchNumber"}
|
|
26
|
+
DEFAULT_CALLBACK_SERVERNAME = "python-server2-0"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
class Status(CIEnum):
|
|
30
|
+
failure = "failure"
|
|
31
|
+
success = "success"
|
|
32
|
+
delete = "delete"
|
|
33
|
+
|
|
34
|
+
@classmethod
|
|
35
|
+
def mapping(cls, status: Union["Status", str]) -> str:
|
|
36
|
+
status = cls[status]
|
|
37
|
+
if status is cls.failure:
|
|
38
|
+
return "0"
|
|
39
|
+
elif status is cls.success:
|
|
40
|
+
return "1"
|
|
41
|
+
else:
|
|
42
|
+
return "2"
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class AsyncAccountingEngines(ElementBase[AccountingEnginesAPI]):
|
|
46
|
+
"""会计引擎"""
|
|
47
|
+
@future_property
|
|
48
|
+
async def meta(self) -> AccountingEnginesDTO:
|
|
49
|
+
"""会计引擎的元数据信息"""
|
|
50
|
+
api = await self.wait_for('async_api')
|
|
51
|
+
element_info = await self.wait_for('element_info')
|
|
52
|
+
return await api.engines.get_accounting_info_by_name_type(
|
|
53
|
+
elementType=element_info.elementType,
|
|
54
|
+
elementName=self.element_name,
|
|
55
|
+
folderId=element_info.folderId,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
async def execute(
|
|
59
|
+
self,
|
|
60
|
+
filter_scope: Dict[str, str] = None,
|
|
61
|
+
callback: Union[Dict, CallbackInfo] = None,
|
|
62
|
+
sync: bool = False,
|
|
63
|
+
) -> Union[DataDTO, None]:
|
|
64
|
+
"""
|
|
65
|
+
执行会计/单据引擎
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
filter_scope: 执行参数,键值对分别表示执行时源数据的数据选择字段和对应范围
|
|
69
|
+
callback: 回调脚本配置信息,若为None,则引擎在结束后不会调用脚本,如果配置了回调,
|
|
70
|
+
则不论引擎是否执行成功,都将在结束后调用回调脚本
|
|
71
|
+
sync: 调用执行接口的类型,同步(True)/异步(False),默认为异步,异步执行接口会
|
|
72
|
+
在收到执行请求时立刻响应,同步执行接口会等执行完成后才响应,并返回执行信息,如果
|
|
73
|
+
设置为同步,当数据量过大导致引擎执行时间过长时,可能因超出SDK的接口响应超时时间而报错
|
|
74
|
+
|
|
75
|
+
Returns:
|
|
76
|
+
调用同步接口时返回执行信息(批次号和执行成功条数),调用异步接口时则返回None
|
|
77
|
+
|
|
78
|
+
.. admonition:: 示例
|
|
79
|
+
|
|
80
|
+
1.以自定义数据选取参数执行
|
|
81
|
+
|
|
82
|
+
.. code-block:: python
|
|
83
|
+
|
|
84
|
+
engines = AccountingEngines('engines_example')
|
|
85
|
+
# engines = BillEngines('engines_example')
|
|
86
|
+
engines.execute(filter_scope={"year": "2022", "period": "10"})
|
|
87
|
+
|
|
88
|
+
2.以默认参数执行
|
|
89
|
+
|
|
90
|
+
.. code-block:: python
|
|
91
|
+
|
|
92
|
+
engines.execute()
|
|
93
|
+
|
|
94
|
+
3.执行并在结束后调用回调脚本
|
|
95
|
+
|
|
96
|
+
.. code-block:: python
|
|
97
|
+
|
|
98
|
+
callback = CallbackInfo(
|
|
99
|
+
path="/Python",
|
|
100
|
+
elementName="test_callback",
|
|
101
|
+
serverName="python-server2-0",
|
|
102
|
+
callbackParams={"key1":"value1", "key2":"value2"},
|
|
103
|
+
)
|
|
104
|
+
# callback = {
|
|
105
|
+
# "path": "/Python",
|
|
106
|
+
# "elementName": "test_callback",
|
|
107
|
+
# "serverName": "python-server2-0",
|
|
108
|
+
# "callbackParams": {"key1":"value1", "key2":"value2"},
|
|
109
|
+
# }
|
|
110
|
+
engines.execute(callback=callback)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
Hint:
|
|
114
|
+
- ``filter_scope`` 参数中传入的键,若为会计引擎全局配置中已配置的字段,则在
|
|
115
|
+
执行时其值会覆盖配置字段的默认值,否则,该键值对会被忽略。
|
|
116
|
+
- ``filter_scope`` 参数中不存在而会计引擎全局配置中已配置的字段,在执行时会
|
|
117
|
+
取配置字段的默认值。
|
|
118
|
+
- ``filter_scope`` 参数可以不传,此时数据选择范围为会计引擎中配置的默认值。
|
|
119
|
+
|
|
120
|
+
Attention:
|
|
121
|
+
``callback`` 可接受字典和CallbackInfo类两种参数,以CallbackInfo类为例,
|
|
122
|
+
其在初始化时支持6个配置参数,如下表所示
|
|
123
|
+
|
|
124
|
+
+----------------+----------------+------------------------------------------------------------------------+
|
|
125
|
+
| 参数 | 类型 | 说明 |
|
|
126
|
+
+================+================+========================================================================+
|
|
127
|
+
| path | Optional[str] | 调用元素所在路径,与folderId二选一 |
|
|
128
|
+
+----------------+----------------+------------------------------------------------------------------------+
|
|
129
|
+
| folderId | Optional[str] | 调用元素所在文件夹ID,与path二选一 |
|
|
130
|
+
+----------------+----------------+------------------------------------------------------------------------+
|
|
131
|
+
| elementName | str | 调用元素的元素名 |
|
|
132
|
+
+----------------+----------------+------------------------------------------------------------------------+
|
|
133
|
+
| elementType | Optional[str] | 元素类型,默认None时指代PY,目前仅支持PY |
|
|
134
|
+
+----------------+----------------+------------------------------------------------------------------------+
|
|
135
|
+
| serverName | Optional[str] | 元素服务名,默认None时指代python-server2-0,目前仅支持python-server2-0 |
|
|
136
|
+
+----------------+----------------+------------------------------------------------------------------------+
|
|
137
|
+
| callbackParams | Optional[Dict] | 传给回调脚本的额外参数 |
|
|
138
|
+
+----------------+----------------+------------------------------------------------------------------------+
|
|
139
|
+
|
|
140
|
+
以示例3的回调参数为例,回调脚本接收到参数为
|
|
141
|
+
|
|
142
|
+
.. code-block:: python
|
|
143
|
+
|
|
144
|
+
p2 = {
|
|
145
|
+
"controlTableInfo": { # 状态控制表信息
|
|
146
|
+
"id": "0a43f4f1-b7b4-4d32-8b6a-c89b58a9b75c",
|
|
147
|
+
"elementName": "accounting_control",
|
|
148
|
+
"elementType": "DAT_MYSQL",
|
|
149
|
+
"folderId": "DIRa020ede38a99",
|
|
150
|
+
"serverName": None,
|
|
151
|
+
"path": "\\test\\",
|
|
152
|
+
"absoluteTag": False,
|
|
153
|
+
"relativePath": None,
|
|
154
|
+
"remark": None,
|
|
155
|
+
"actualTableName": "tb001_accounting_control",
|
|
156
|
+
},
|
|
157
|
+
"success": True, # 引擎是否执行成功
|
|
158
|
+
"key1": "value1", # 自定义参数
|
|
159
|
+
"key2": "value2", # 自定义参数
|
|
160
|
+
"batchNumber": "127559e5-de2a-42c2-95d9-1c84e1a6483b_20221129173222", # 批次号
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
自定义参数的名称不应当为controlTableInfo、success或batchNumber,以免和回调脚本传入的默认参数冲突
|
|
164
|
+
|
|
165
|
+
"""
|
|
166
|
+
if callback:
|
|
167
|
+
if isinstance(callback, Dict):
|
|
168
|
+
callback = CallbackInfo(**callback)
|
|
169
|
+
if not callback.serverName:
|
|
170
|
+
callback.serverName = DEFAULT_CALLBACK_SERVERNAME
|
|
171
|
+
if conflicts := DEFAULT_CALLBACK_PARAMS.intersection(callback.callbackParams or []):
|
|
172
|
+
raise ValueError(
|
|
173
|
+
f"Name: {conflicts} are reserved thus cannot be used "
|
|
174
|
+
f"as callback parameter names."
|
|
175
|
+
)
|
|
176
|
+
request_body = AccountingEnginesRequestDTO(
|
|
177
|
+
elementName=self.element_name,
|
|
178
|
+
folderId=self.element_info.folderId,
|
|
179
|
+
elementType=self.element_info.elementType,
|
|
180
|
+
paramValueMap=filter_scope,
|
|
181
|
+
callbackInfo=callback,
|
|
182
|
+
)
|
|
183
|
+
if sync:
|
|
184
|
+
return await self.async_api.engines.exec_by_id(request_body)
|
|
185
|
+
else:
|
|
186
|
+
return await self.async_api.engines.sync_exec_by_id(request_body)
|
|
187
|
+
|
|
188
|
+
async def update_status(self, key: List[str], status: Union[Status, str]) -> None:
|
|
189
|
+
"""修改执行状态
|
|
190
|
+
|
|
191
|
+
Args:
|
|
192
|
+
key: 目标模型主表的业务主键的值
|
|
193
|
+
status: 执行状态,字符串类型
|
|
194
|
+
|
|
195
|
+
.. admonition:: 示例
|
|
196
|
+
|
|
197
|
+
.. code-block:: python
|
|
198
|
+
|
|
199
|
+
engines.update_status(key=["A_2022_8_0046", "100001"], status='delete')
|
|
200
|
+
|
|
201
|
+
Hint:
|
|
202
|
+
- ``key`` 参数表示目标模型中需要修改执行状态的业务主键字段的值。
|
|
203
|
+
- ``status`` 参数表示需要修改成的执行状态,一般业务场景下设置为delete,
|
|
204
|
+
表示执行状态改为删除。
|
|
205
|
+
|
|
206
|
+
Attention:
|
|
207
|
+
- status执行状态可选参数如下:
|
|
208
|
+
|
|
209
|
+
+---------+----------------------+
|
|
210
|
+
| 参数 | 说明 |
|
|
211
|
+
+=========+======================+
|
|
212
|
+
| failure | 修改执行状态为失败。 |
|
|
213
|
+
+---------+----------------------+
|
|
214
|
+
| success | 修改执行状态为成功。 |
|
|
215
|
+
+---------+----------------------+
|
|
216
|
+
| delete | 修改执行状态为删除。 |
|
|
217
|
+
+---------+----------------------+
|
|
218
|
+
|
|
219
|
+
- 会计/单据引擎组件在内部会维护一张源对象和目标模型的主键映射表,并记录其执行状态。
|
|
220
|
+
|
|
221
|
+
+------------+------------------+----------+
|
|
222
|
+
| 源对象主键 | 目标模型主表主键 | 执行状态 |
|
|
223
|
+
+============+==================+==========+
|
|
224
|
+
| A_000001 | A_2022_8_0046 | success |
|
|
225
|
+
+------------+------------------+----------+
|
|
226
|
+
| A_000002 | A_2022_8_0046 | success |
|
|
227
|
+
+------------+------------------+----------+
|
|
228
|
+
| A_000003 | A_2022_8_0047 | delete |
|
|
229
|
+
+------------+------------------+----------+
|
|
230
|
+
|
|
231
|
+
- 对于执行状态为成功的目标模型数据,其关联的源对象数据在再次执行会计/单据引擎时不
|
|
232
|
+
会二次计算。因此,当目标模型中会计/单据引擎生成的数据被通过非会计/单据引擎组件提供的
|
|
233
|
+
手段被删除时,必须主动将被删除数据的执行状态修改为delete(删除)。
|
|
234
|
+
- 如果有其他业务场景,需要修改源对象和目标模型的主键映射表的执行状态为failure
|
|
235
|
+
或success,也可以调用该接口。
|
|
236
|
+
"""
|
|
237
|
+
|
|
238
|
+
return await self.async_api.engines.update_control_status(
|
|
239
|
+
AccountingControlRequestDTO(
|
|
240
|
+
elementName=self.element_name,
|
|
241
|
+
folderId=self.element_info.folderId,
|
|
242
|
+
elementType=self.element_info.elementType,
|
|
243
|
+
status=Status.mapping(status),
|
|
244
|
+
targetElementDataIdList=key,
|
|
245
|
+
)
|
|
246
|
+
)
|
|
247
|
+
|
|
248
|
+
|
|
249
|
+
class AccountingEngines(AsyncAccountingEngines, metaclass=SyncMeta):
|
|
250
|
+
synchronize = (
|
|
251
|
+
'execute',
|
|
252
|
+
'update_status'
|
|
253
|
+
)
|
|
254
|
+
if TYPE_CHECKING: # pragma: no cover
|
|
255
|
+
def execute(
|
|
256
|
+
self,
|
|
257
|
+
filter_scope: Dict[str, str] = None,
|
|
258
|
+
callback: Union[Dict, CallbackInfo] = None,
|
|
259
|
+
sync: bool = False,
|
|
260
|
+
) -> Union[DataDTO, None]:
|
|
261
|
+
...
|
|
262
|
+
|
|
263
|
+
def update_status(self, key: List[str], status: Union[Status, str]) -> None:
|
|
264
|
+
...
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
class AsyncBillEngines(AsyncAccountingEngines):
|
|
268
|
+
"""单据引擎"""
|
|
269
|
+
|
|
270
|
+
api_class = BillEnginesAPI
|
|
271
|
+
api: BillEnginesAPI
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
class BillEngines(AccountingEngines):
|
|
275
|
+
"""单据引擎"""
|
|
276
|
+
|
|
277
|
+
api_class = BillEnginesAPI
|
|
278
|
+
api: BillEnginesAPI
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
class AsyncAccountingEventType(ElementBase[AccountingEventTypeAPI]):
|
|
282
|
+
"""会计事件类型"""
|
|
283
|
+
@future_property
|
|
284
|
+
async def meta(self) -> AccEventTypeElementDTO:
|
|
285
|
+
"""会计事件类型元数据信息"""
|
|
286
|
+
api = await self.wait_for('async_api')
|
|
287
|
+
element_info = await self.wait_for('element_info')
|
|
288
|
+
return await api.engines.get_info_by_name(
|
|
289
|
+
elementType=element_info.elementType,
|
|
290
|
+
elementName=self.element_name,
|
|
291
|
+
folderId=element_info.folderId
|
|
292
|
+
)
|
|
293
|
+
|
|
294
|
+
async def insert_to_event_table(self, object_id_list: List[str]) -> None:
|
|
295
|
+
"""业务主健插入会计事件表
|
|
296
|
+
|
|
297
|
+
Args:
|
|
298
|
+
object_id_list: 业务主键ID集合
|
|
299
|
+
|
|
300
|
+
.. admonition:: 示例
|
|
301
|
+
|
|
302
|
+
1.实例化会计事件类型
|
|
303
|
+
|
|
304
|
+
.. code-block:: python
|
|
305
|
+
|
|
306
|
+
from deepfos.element.accounting import AccountingEventType
|
|
307
|
+
# 1. 根据元素编码 进行实例化
|
|
308
|
+
eventType = AccountingEventType('zhy_0104_001')
|
|
309
|
+
|
|
310
|
+
# 2. 根据元素编码和路径 进行实例化
|
|
311
|
+
eventType = AccountingEventType(element_name='zhy_0104_001',path="/zhy_test/event")
|
|
312
|
+
|
|
313
|
+
# 3. 根据元素编码和文件夹ID,进行实例化
|
|
314
|
+
eventType = AccountingEventType(element_name='zhy_0104_001',folder_id='DIR1b7e6f8b5bc3')
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
2.业务主健插入会计事件表
|
|
318
|
+
|
|
319
|
+
.. code-block:: python
|
|
320
|
+
|
|
321
|
+
# 1. 指定参数名 object_id_list,并传业务ID集合
|
|
322
|
+
eventType.insert_to_event_table(object_id_list=["A00000002","A00000003"])
|
|
323
|
+
|
|
324
|
+
# 2. 不指定参数名,直接传业务ID集合
|
|
325
|
+
eventType.insert_to_event_table(["A00000004","A00000005"])
|
|
326
|
+
|
|
327
|
+
Hint:
|
|
328
|
+
- ``object_id_list`` 业务主键ID集合,
|
|
329
|
+
表示将业务主键集合,插入到会计事件类型元素(zhy_0104_001)对应的事件表中。
|
|
330
|
+
|
|
331
|
+
"""
|
|
332
|
+
|
|
333
|
+
return await self.async_api.engines.insert_to_event_table(
|
|
334
|
+
AccEventTypeTableDTO(
|
|
335
|
+
elementName=self.element_name,
|
|
336
|
+
folderId=self.element_info.folderId,
|
|
337
|
+
objectIdList=object_id_list
|
|
338
|
+
)
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
|
|
342
|
+
class AccountingEventType(AsyncAccountingEventType, metaclass=SyncMeta):
|
|
343
|
+
synchronize = (
|
|
344
|
+
'insert_to_event_table',
|
|
345
|
+
)
|
|
346
|
+
if TYPE_CHECKING: # pragma: no cover
|
|
347
|
+
def insert_to_event_table(self, object_id_list: List[str]) -> None:
|
|
348
|
+
...
|