data-ops-cli 0.2.2__py3-none-any.whl → 0.2.3__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.
- {data_ops_cli-0.2.2.dist-info → data_ops_cli-0.2.3.dist-info}/METADATA +1 -1
- {data_ops_cli-0.2.2.dist-info → data_ops_cli-0.2.3.dist-info}/RECORD +27 -23
- dataops_cli/__init__.py +1 -1
- dataops_cli/cli/dataset.py +3 -4
- dataops_cli/cli/datasource.py +99 -2
- dataops_cli/cli/dict_.py +96 -0
- dataops_cli/cli/factory.py +2 -0
- dataops_cli/cli/table.py +85 -2
- dataops_cli/schems/__init__.py +9 -2
- dataops_cli/schems/data_table.py +3 -41
- dataops_cli/schems/datasource.py +15 -49
- dataops_cli/schems/dict_.py +13 -0
- dataops_cli/schems/enums.py +39 -0
- dataops_cli/schems/meta.py +15 -4
- dataops_cli/schems/table.py +59 -7
- dataops_cli/sdk/__init__.py +8 -3
- dataops_cli/sdk/auth.py +0 -8
- dataops_cli/sdk/data_table.py +5 -8
- dataops_cli/sdk/dataset.py +54 -0
- dataops_cli/sdk/datasource.py +6 -6
- dataops_cli/sdk/dict_.py +69 -0
- dataops_cli/sdk/meta.py +28 -12
- dataops_cli/sdk/table.py +8 -45
- dataops_cli/session.py +40 -1
- {data_ops_cli-0.2.2.dist-info → data_ops_cli-0.2.3.dist-info}/WHEEL +0 -0
- {data_ops_cli-0.2.2.dist-info → data_ops_cli-0.2.3.dist-info}/entry_points.txt +0 -0
- {data_ops_cli-0.2.2.dist-info → data_ops_cli-0.2.3.dist-info}/top_level.txt +0 -0
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
dataops_cli/__init__.py,sha256=
|
|
1
|
+
dataops_cli/__init__.py,sha256=PNiDER4qM19h9zdsdfgKt2_dT4WgYK7EguJ8RU2qA_g,22
|
|
2
2
|
dataops_cli/constants.py,sha256=Nc0ZofLF_sX_wDyVDvvrZPKOj6c_jahEOXmhy5phvF8,293
|
|
3
3
|
dataops_cli/exceptions.py,sha256=GnNqDlMfgjMiL0Kp-H0KZMDJdRAckG6kd3V-NJiugFg,575
|
|
4
|
-
dataops_cli/session.py,sha256=
|
|
4
|
+
dataops_cli/session.py,sha256=TnI-4MAMQYBxsTu5yvaxwSqGoBEytV2xakvVIyADudU,6632
|
|
5
5
|
dataops_cli/utils.py,sha256=-7iBbYjp9JM5LhuCkNhYoNITa26YJxyhd_oTYzPjERU,3740
|
|
6
6
|
dataops_cli/cli/__init__.py,sha256=TvJw3xrE81YSwUrauHaJwQsRNf-YAlxLnadce1KYo4c,67
|
|
7
7
|
dataops_cli/cli/auth.py,sha256=7kM0c0hjALZ-u7-RsNZhwRct5kshA2S5_zmqSlFVzc4,6381
|
|
8
8
|
dataops_cli/cli/data_table.py,sha256=vzzC7naHBNKe5aYsxjkFUdTHkQrkgsVHY3w_SGi3tKo,9402
|
|
9
|
-
dataops_cli/cli/dataset.py,sha256=
|
|
10
|
-
dataops_cli/cli/datasource.py,sha256=
|
|
11
|
-
dataops_cli/cli/
|
|
9
|
+
dataops_cli/cli/dataset.py,sha256=s7I5SCsHcA4r2bK-jAqKrywAgMxuRkE4QDaU5KZ82cM,3287
|
|
10
|
+
dataops_cli/cli/datasource.py,sha256=3KCYt8DWlnYu0bCqARqDsUOXzDSfTPfeLsDL4XZP6xs,7306
|
|
11
|
+
dataops_cli/cli/dict_.py,sha256=UwF3MS6_eXon1v4w5b0tm0qCcIuQ5OBYUndxJFDPFhw,3101
|
|
12
|
+
dataops_cli/cli/factory.py,sha256=f7fZ5ElyUtynJ_-twAT_LC6ILjCmWS-k7WFDkPuS80M,1632
|
|
12
13
|
dataops_cli/cli/metrics.py,sha256=CioC_l2DHlg3s97_-kAfLihdz7tLgOwb9lo2AIngb5I,6195
|
|
13
14
|
dataops_cli/cli/ref.py,sha256=jfc5EhkXrhqUwu4IuftEjUepPB3d6SK4ZDhrh40YGOE,4765
|
|
14
15
|
dataops_cli/cli/report.py,sha256=-qo5Nz31bCI_y8dvPoBnpn4-ggQ0Leo5mUsmiWBzNJ8,2437
|
|
15
|
-
dataops_cli/cli/table.py,sha256=
|
|
16
|
+
dataops_cli/cli/table.py,sha256=ybogQ4DY6wWs29rEtxNx0ztwaV0OzlYPkPp2TCdsl8M,11224
|
|
16
17
|
dataops_cli/cli/utils.py,sha256=Qi3BGmZgIapasHAGCYVdOS8deYz5GmZIqKd289HYgeE,529
|
|
17
18
|
dataops_cli/cli/widget.py,sha256=7Kzie7GqNf1vLK2O9G1HVSJnzjUGRHJqGaypVCEkLsE,1745
|
|
18
19
|
dataops_cli/cli/workflow.py,sha256=Do0bwV9kHSSOICW5RELLJoL34fLhf7tIcqcOSokKFLw,4804
|
|
@@ -35,26 +36,29 @@ dataops_cli/runner/utils/duckdb_manager.py,sha256=xIREgkx6hcAbt6cYSTEHfGPGu7QgZs
|
|
|
35
36
|
dataops_cli/runner/utils/log.py,sha256=EwctSAohPIP1wo2FtUTjv5kswyoGHK70-2CFlyQ9yN4,1438
|
|
36
37
|
dataops_cli/runner/utils/nacos.py,sha256=HSJyjswRk1ohzzUEjn4yRDtWKPjgsU_yYoS1nh5TWss,2994
|
|
37
38
|
dataops_cli/runner/utils/neo4j_sync.py,sha256=cbpb4K5QUHcD1DuJg7_KeoBi8N1DLwru2sbiDMq779M,6603
|
|
38
|
-
dataops_cli/schems/__init__.py,sha256=
|
|
39
|
-
dataops_cli/schems/data_table.py,sha256=
|
|
40
|
-
dataops_cli/schems/datasource.py,sha256=
|
|
41
|
-
dataops_cli/schems/
|
|
39
|
+
dataops_cli/schems/__init__.py,sha256=zbhX7c9tVO8I5OEXH05Cny5je9Dz8N36yicv-Fw5rHg,744
|
|
40
|
+
dataops_cli/schems/data_table.py,sha256=tLCOcaTMIoM5KySHYE97YSqBly95cjlbmyZcUZL1Lv0,16516
|
|
41
|
+
dataops_cli/schems/datasource.py,sha256=gSFoQm5ZNhn3PxcrM24WLpvJcT_QHOhNp_2J3cbIT6A,854
|
|
42
|
+
dataops_cli/schems/dict_.py,sha256=Y0ebyXYCw4vBhBgHyPXCz_4yVALAxMkQQlxSQsjJNs0,394
|
|
43
|
+
dataops_cli/schems/enums.py,sha256=9gB08DPwAr2gthzuxew0pI91e8byaVH34I03eu4kDhc,2111
|
|
42
44
|
dataops_cli/schems/group.py,sha256=TvH0nsrGz1DpftrLAPpHqQuhMNgu0e5gu_Og3PiVnBc,1306
|
|
43
|
-
dataops_cli/schems/meta.py,sha256=
|
|
45
|
+
dataops_cli/schems/meta.py,sha256=mLf4Fk1Dgw14hCDkWvS-cJcrV649NiHJ50_WZO9na6Y,6241
|
|
44
46
|
dataops_cli/schems/query.py,sha256=AWH0P51lkBQEKhotIOoqJaOEIEoaWaiT_r7hSXlzK2Q,6455
|
|
45
47
|
dataops_cli/schems/report.py,sha256=Eklh1gMaRoPDvgrWZIBrLkQXhB0KuuAteJUzOzZngb8,493
|
|
46
|
-
dataops_cli/schems/table.py,sha256=
|
|
48
|
+
dataops_cli/schems/table.py,sha256=ZXsNWQ0whu1UT1UsXaFufCgUu4jlkjs9-G9zn7Teo4g,2557
|
|
47
49
|
dataops_cli/schems/user.py,sha256=mAPgLCCKeoC7qvOj6TOSC2xI3OrL7P5eNOGy4R3RVyw,2522
|
|
48
50
|
dataops_cli/schems/widget.py,sha256=q1zsVv9g0bS_Fev_IRzHaH86T3cQfwzS5fcm5VhVMrM,21691
|
|
49
51
|
dataops_cli/schems/workflow.py,sha256=opRkEwYXntTO-BCOLcZJK2joA32qELpdnN6pI2LS_2Y,1805
|
|
50
|
-
dataops_cli/sdk/__init__.py,sha256=
|
|
51
|
-
dataops_cli/sdk/auth.py,sha256=
|
|
52
|
-
dataops_cli/sdk/data_table.py,sha256=
|
|
53
|
-
dataops_cli/sdk/
|
|
54
|
-
dataops_cli/sdk/
|
|
52
|
+
dataops_cli/sdk/__init__.py,sha256=lXHkapsvcLkQv23HIumV_JAl85Z9ukvSXxLh8629ehw,1134
|
|
53
|
+
dataops_cli/sdk/auth.py,sha256=xA3x99lv5x1vgcy66pGvdh8Dw2OQc82Npku9iNOcXXs,3729
|
|
54
|
+
dataops_cli/sdk/data_table.py,sha256=7focA6HBv-4nwbIrBdZ4-S7ull-EjP3MuG4tYWghK6U,6827
|
|
55
|
+
dataops_cli/sdk/dataset.py,sha256=2qb52OVGhU6XAxeVjJoTjdazLNAmT9L9yxgIlphd7-4,1268
|
|
56
|
+
dataops_cli/sdk/datasource.py,sha256=WrCFkBVxsQSiHFBEiA7yMfDTp448LU-tU5KG1jwWtN0,2061
|
|
57
|
+
dataops_cli/sdk/dict_.py,sha256=RLsvlrC-ARYXPudLczGOySmFp-z3p8yjw6QujL59Qc0,1790
|
|
58
|
+
dataops_cli/sdk/meta.py,sha256=kOxVAle1ThpwkNlqZoqpYzrT3E_qUY-WFHB68bpW0Vs,16915
|
|
55
59
|
dataops_cli/sdk/ref.py,sha256=BPttMiqaW7z1nuCvgY0nV6d-u1O1i_EbEJ7ZrL0KhFY,1925
|
|
56
60
|
dataops_cli/sdk/report.py,sha256=uBmfgPCzqRMJQk8yS3kqSMLgOKijKEDRNOWamhjC6mw,376
|
|
57
|
-
dataops_cli/sdk/table.py,sha256=
|
|
61
|
+
dataops_cli/sdk/table.py,sha256=aUT9arVndrP8X9TZ4ctQLGpwkVqgNy5_XkoF_GisKbA,5696
|
|
58
62
|
dataops_cli/sdk/workflow.py,sha256=go39E4Cc96bEuNW0pGeDvZZwonkKQ5njMaFTwLW-3jE,472
|
|
59
63
|
dataops_cli/tiptap/__init__.py,sha256=UaHc1Q0T6OtmN02WNxTY1tp1-Iw8wzZjIyZE6rlMBgQ,612
|
|
60
64
|
dataops_cli/tiptap/builder.py,sha256=w8lzbCcRo-AOFRvOoN3b_JV4hNLch_iSPbcYIcSqelk,2245
|
|
@@ -64,8 +68,8 @@ dataops_cli/tiptap/parse_utils.py,sha256=iJ4_gean-tkPXks4UShXuyPAkUwwFh41WL6cS7G
|
|
|
64
68
|
dataops_cli/tiptap/render_utils.py,sha256=f5CDNLm0Y3uPXD0oPEjq4cKw1hDvWviY3IVlfS05vzE,21021
|
|
65
69
|
dataops_cli/tiptap/renderers.py,sha256=qHAeYZeJf1Wip0svKtmy-28uFSeoTELzh3iE8bAQwaw,1235
|
|
66
70
|
dataops_cli/tiptap/tool.py,sha256=7Uxoq-Kv_3XzU5ZW0k16wzwz79nhQf8D6qq7ygxERLw,27902
|
|
67
|
-
data_ops_cli-0.2.
|
|
68
|
-
data_ops_cli-0.2.
|
|
69
|
-
data_ops_cli-0.2.
|
|
70
|
-
data_ops_cli-0.2.
|
|
71
|
-
data_ops_cli-0.2.
|
|
71
|
+
data_ops_cli-0.2.3.dist-info/METADATA,sha256=Vhyg3gc9qKSElb34u-hSPGn4tvFcBn3o-soqevOhHpo,503
|
|
72
|
+
data_ops_cli-0.2.3.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
|
|
73
|
+
data_ops_cli-0.2.3.dist-info/entry_points.txt,sha256=vc_2b5byVdLofaQ2ppuPM484AcaZnGsaHdcMKmtcSkU,53
|
|
74
|
+
data_ops_cli-0.2.3.dist-info/top_level.txt,sha256=KFHplpKxwE9_wWypzVLESa4eLkOBsk-iUD_Qbld2IcY,12
|
|
75
|
+
data_ops_cli-0.2.3.dist-info/RECORD,,
|
dataops_cli/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.2.
|
|
1
|
+
__version__ = "0.2.3"
|
dataops_cli/cli/dataset.py
CHANGED
|
@@ -5,8 +5,7 @@ from rich.console import Console
|
|
|
5
5
|
from rich.table import Table
|
|
6
6
|
|
|
7
7
|
from dataops_cli.exceptions import DataOpsError
|
|
8
|
-
from dataops_cli.
|
|
9
|
-
from dataops_cli.sdk.meta import release_list_get_by_code, release_list_list
|
|
8
|
+
from dataops_cli.sdk import service_get_dataset_detail_by_code, service_list_datasets
|
|
10
9
|
from dataops_cli.utils import filter_nodes_by_pattern
|
|
11
10
|
|
|
12
11
|
dataset_typer = typer.Typer(name="dataset", help="Manage dataset.", no_args_is_help=True)
|
|
@@ -28,7 +27,7 @@ def list_dataset(
|
|
|
28
27
|
>>> data-ops-cli dataset list "HHI.*"
|
|
29
28
|
"""
|
|
30
29
|
try:
|
|
31
|
-
group_nodes =
|
|
30
|
+
group_nodes = service_list_datasets()
|
|
32
31
|
except DataOpsError as e:
|
|
33
32
|
typer.echo(f"错误: {e.message}")
|
|
34
33
|
raise typer.Exit(code=1) from None
|
|
@@ -61,7 +60,7 @@ def get_dataset_detail_by_code(
|
|
|
61
60
|
>>> data-ops-cli dataset detail my_dataset_code --full
|
|
62
61
|
"""
|
|
63
62
|
try:
|
|
64
|
-
meta =
|
|
63
|
+
meta = service_get_dataset_detail_by_code(code)
|
|
65
64
|
except DataOpsError as e:
|
|
66
65
|
typer.echo(f"错误: {e.message}")
|
|
67
66
|
raise typer.Exit(code=1) from None
|
dataops_cli/cli/datasource.py
CHANGED
|
@@ -16,10 +16,19 @@ from rich.table import Table
|
|
|
16
16
|
|
|
17
17
|
from dataops_cli.exceptions import DataOpsError
|
|
18
18
|
from dataops_cli.schems import (
|
|
19
|
+
DataDataSource,
|
|
19
20
|
InnerMetaType,
|
|
21
|
+
MetaCreate,
|
|
22
|
+
MetaUpdate,
|
|
20
23
|
)
|
|
24
|
+
from dataops_cli.schems.enums import DataSourceType
|
|
21
25
|
from dataops_cli.sdk.datasource import get_application_datasource_config, get_datasource
|
|
22
|
-
from dataops_cli.sdk.meta import
|
|
26
|
+
from dataops_cli.sdk.meta import (
|
|
27
|
+
release_list_create,
|
|
28
|
+
release_list_get_by_name,
|
|
29
|
+
release_list_list,
|
|
30
|
+
release_list_update,
|
|
31
|
+
)
|
|
23
32
|
from dataops_cli.sdk.table import (
|
|
24
33
|
service_get_table_data_by_name,
|
|
25
34
|
)
|
|
@@ -95,5 +104,93 @@ def list_datasource(
|
|
|
95
104
|
console.print(table)
|
|
96
105
|
|
|
97
106
|
|
|
107
|
+
@datasource_typer.command("detail")
|
|
108
|
+
def get_datasource_detail(
|
|
109
|
+
name: Annotated[str, typer.Argument(help="数据源名称")],
|
|
110
|
+
) -> None:
|
|
111
|
+
"""获取指定数据源的详细信息.
|
|
112
|
+
|
|
113
|
+
Args:
|
|
114
|
+
name: 数据源名称
|
|
115
|
+
"""
|
|
116
|
+
meta = release_list_get_by_name(InnerMetaType.DATASOURCE.value, name, _class=DataDataSource)
|
|
117
|
+
table = Table("field", "value", show_header=False)
|
|
118
|
+
table.add_row("name", meta.name)
|
|
119
|
+
table.add_row("title", meta.title)
|
|
120
|
+
table.add_row("分组", meta.groupCode)
|
|
121
|
+
table.add_row("数据库类型", meta.data.type.value)
|
|
122
|
+
table.add_row("地址", meta.data.ip)
|
|
123
|
+
table.add_row("端口", str(meta.data.port))
|
|
124
|
+
table.add_row("数据库账户", meta.data.username)
|
|
125
|
+
table.add_row("说明", meta.remark or "")
|
|
126
|
+
console = Console(no_color=True)
|
|
127
|
+
console.print(table)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
@datasource_typer.command("create", no_args_is_help=True)
|
|
131
|
+
def create_datasource(
|
|
132
|
+
name: Annotated[str, typer.Option(help="数据源名称")],
|
|
133
|
+
title: Annotated[str, typer.Option(help="数据源中文名称")],
|
|
134
|
+
type: Annotated[DataSourceType, typer.Option("-t", "--type", help="数据源类型")],
|
|
135
|
+
ip: Annotated[str, typer.Option(help="数据源 IP 地址")],
|
|
136
|
+
port: Annotated[int, typer.Option("-p", "--port", help="数据源端口号")],
|
|
137
|
+
username: Annotated[str, typer.Option("-u", "--username", help="数据源用户名")],
|
|
138
|
+
password: Annotated[str, typer.Option(help="数据源密码", hide_input=True)],
|
|
139
|
+
database: Annotated[str, typer.Option("-db", "--database", help="数据库名称")],
|
|
140
|
+
remark: Annotated[str | None, typer.Option(help="数据源备注")] = None,
|
|
141
|
+
) -> None:
|
|
142
|
+
"""创建新的数据源."""
|
|
143
|
+
meta_create = MetaCreate[DataDataSource](
|
|
144
|
+
type="datasource",
|
|
145
|
+
subType=f"database__{type.value}",
|
|
146
|
+
name=name,
|
|
147
|
+
title=title,
|
|
148
|
+
remark=remark,
|
|
149
|
+
groupCode="inner",
|
|
150
|
+
data=DataDataSource(
|
|
151
|
+
type=type, ip=ip, port=port, username=username, password=password, database=database
|
|
152
|
+
),
|
|
153
|
+
)
|
|
154
|
+
result = release_list_create(meta_create, _class=DataDataSource)
|
|
155
|
+
typer.echo(f"数据源 {result.name} 创建成功")
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
@datasource_typer.command("update", no_args_is_help=True)
|
|
159
|
+
def update_datasource(
|
|
160
|
+
name: Annotated[str, typer.Argument(help="数据源名称")],
|
|
161
|
+
title: Annotated[str | None, typer.Option(help="数据源中文名称")] = None,
|
|
162
|
+
type: Annotated[DataSourceType | None, typer.Option("-t", "--type", help="数据源类型")] = None,
|
|
163
|
+
ip: Annotated[str | None, typer.Option(help="数据源 IP 地址")] = None,
|
|
164
|
+
port: Annotated[int | None, typer.Option("-p", "--port", help="数据源端口号")] = None,
|
|
165
|
+
username: Annotated[str | None, typer.Option("-u", "--username", help="数据源用户名")] = None,
|
|
166
|
+
password: Annotated[str | None, typer.Option(help="数据源密码", hide_input=True)] = None,
|
|
167
|
+
database: Annotated[str | None, typer.Option("-db", "--database", help="数据库名称")] = None,
|
|
168
|
+
remark: Annotated[str | None, typer.Option(help="数据源备注")] = None,
|
|
169
|
+
) -> None:
|
|
170
|
+
"""更新已有的数据源."""
|
|
171
|
+
meta = release_list_get_by_name(InnerMetaType.DATASOURCE.value, name, _class=DataDataSource)
|
|
172
|
+
if type:
|
|
173
|
+
meta.data.type = type
|
|
174
|
+
meta.subType = f"database__{type.value}"
|
|
175
|
+
if title:
|
|
176
|
+
meta.title = title
|
|
177
|
+
if ip:
|
|
178
|
+
meta.data.ip = ip
|
|
179
|
+
if port:
|
|
180
|
+
meta.data.port = port
|
|
181
|
+
if username:
|
|
182
|
+
meta.data.username = username
|
|
183
|
+
if password:
|
|
184
|
+
meta.data.password = password
|
|
185
|
+
if database:
|
|
186
|
+
meta.data.database = database
|
|
187
|
+
if remark:
|
|
188
|
+
meta.remark = remark
|
|
189
|
+
|
|
190
|
+
result = release_list_update(meta, _class=DataDataSource)
|
|
191
|
+
typer.echo(f"数据源 {result.name} 更新成功")
|
|
192
|
+
|
|
193
|
+
|
|
98
194
|
if __name__ == "__main__":
|
|
99
|
-
|
|
195
|
+
print(DataDataSource.model_json_schema())
|
|
196
|
+
# list_datasource("doris")
|
dataops_cli/cli/dict_.py
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
from typing import Annotated, Optional
|
|
2
|
+
|
|
3
|
+
import typer
|
|
4
|
+
from rich.console import Console
|
|
5
|
+
from rich.table import Table
|
|
6
|
+
|
|
7
|
+
from dataops_cli.exceptions import DataOpsError
|
|
8
|
+
from dataops_cli.sdk.dict_ import (
|
|
9
|
+
service_get_dict_detail_by_code,
|
|
10
|
+
service_get_dict_detail_by_name,
|
|
11
|
+
service_list_dicts,
|
|
12
|
+
)
|
|
13
|
+
from dataops_cli.utils import filter_nodes_by_pattern
|
|
14
|
+
|
|
15
|
+
dict_typer = typer.Typer(name="dict", help="Manage dict.", no_args_is_help=True)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
@dict_typer.command("list")
|
|
19
|
+
def list_dict(
|
|
20
|
+
datasource: Annotated[str, typer.Argument(help="数据源")],
|
|
21
|
+
query: Annotated[str | None, typer.Argument(help="字典名称关键字")] = None,
|
|
22
|
+
) -> None:
|
|
23
|
+
"""列出数据源中的字典列表.
|
|
24
|
+
|
|
25
|
+
支持通过关键字过滤字典名称,并支持正则表达式匹配。
|
|
26
|
+
|
|
27
|
+
示例:
|
|
28
|
+
# 列出指定数据源的所有字典
|
|
29
|
+
>>> data-ops-cli dict list <datasource>
|
|
30
|
+
|
|
31
|
+
# 列出数据源中名称包含 "user" 的字典
|
|
32
|
+
>>> data-ops-cli dict list <datasource> user
|
|
33
|
+
|
|
34
|
+
# 使用正则过滤字典名
|
|
35
|
+
>>> data-ops-cli dict list <datasource> "^user_.*"
|
|
36
|
+
"""
|
|
37
|
+
try:
|
|
38
|
+
group_nodes = service_list_dicts(datasource)
|
|
39
|
+
except DataOpsError as e:
|
|
40
|
+
typer.echo(f"错误: {e.message}")
|
|
41
|
+
raise typer.Exit(code=1) from None
|
|
42
|
+
|
|
43
|
+
if not group_nodes:
|
|
44
|
+
print("未查询到匹配字典")
|
|
45
|
+
return
|
|
46
|
+
|
|
47
|
+
if query:
|
|
48
|
+
group_nodes = filter_nodes_by_pattern(group_nodes, query)
|
|
49
|
+
|
|
50
|
+
table = Table("code", "name", "alias", "remark", title="dict list")
|
|
51
|
+
console = Console(no_color=True)
|
|
52
|
+
for column in group_nodes:
|
|
53
|
+
table.add_row(column.CODE, column.NAME, column.TITLE)
|
|
54
|
+
console.print(table)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@dict_typer.command("detail", no_args_is_help=True)
|
|
58
|
+
def get_dict_detail(
|
|
59
|
+
arg1: Annotated[str, typer.Argument(help="编码或数据源")],
|
|
60
|
+
name: Annotated[Optional[str], typer.Argument(help="字典名称")] = None,
|
|
61
|
+
full: Annotated[bool, typer.Option("--full", help="是否显示完整信息")] = False,
|
|
62
|
+
) -> None:
|
|
63
|
+
"""获取字典详情信息.
|
|
64
|
+
|
|
65
|
+
支持两种查询方式:
|
|
66
|
+
1. 通过字典编码(CODE)直接查询
|
|
67
|
+
2. 通过数据源名称和字典名称组合查询
|
|
68
|
+
|
|
69
|
+
默认只显示字典选项的基本信息(label/value)。
|
|
70
|
+
使用 --full 选项可显示完整信息。
|
|
71
|
+
|
|
72
|
+
示例:
|
|
73
|
+
# 通过字典编码查询字典结构
|
|
74
|
+
>>> data-ops-cli dict detail dict_code_123
|
|
75
|
+
|
|
76
|
+
# 通过数据源和字典名查询
|
|
77
|
+
>>> data-ops-cli dict detail <datasource> my_dict
|
|
78
|
+
|
|
79
|
+
# 显示完整的字典信息
|
|
80
|
+
>>> data-ops-cli dict detail <datasource> my_dict --full
|
|
81
|
+
"""
|
|
82
|
+
try:
|
|
83
|
+
meta = (
|
|
84
|
+
service_get_dict_detail_by_name(arg1, name)
|
|
85
|
+
if name
|
|
86
|
+
else service_get_dict_detail_by_code(arg1)
|
|
87
|
+
)
|
|
88
|
+
except DataOpsError as e:
|
|
89
|
+
typer.echo(f"错误: {e.message}")
|
|
90
|
+
raise typer.Exit(code=1) from None
|
|
91
|
+
|
|
92
|
+
console = Console(no_color=True)
|
|
93
|
+
table = Table("value", "label", title=f"{arg1} {meta.name} dict")
|
|
94
|
+
for option in meta.data.options:
|
|
95
|
+
table.add_row(str(option.value), option.label)
|
|
96
|
+
console.print(table)
|
dataops_cli/cli/factory.py
CHANGED
|
@@ -29,6 +29,7 @@ def create_app():
|
|
|
29
29
|
from dataops_cli.cli.data_table import data_table_typer
|
|
30
30
|
from dataops_cli.cli.dataset import dataset_typer
|
|
31
31
|
from dataops_cli.cli.datasource import datasource_typer
|
|
32
|
+
from dataops_cli.cli.dict_ import dict_typer
|
|
32
33
|
from dataops_cli.cli.metrics import metrics_typer
|
|
33
34
|
from dataops_cli.cli.ref import ref_typer
|
|
34
35
|
from dataops_cli.cli.report import report_typer
|
|
@@ -52,6 +53,7 @@ def create_app():
|
|
|
52
53
|
app.add_typer(metrics_typer)
|
|
53
54
|
app.add_typer(data_table_typer)
|
|
54
55
|
app.add_typer(widget_typer)
|
|
56
|
+
app.add_typer(dict_typer)
|
|
55
57
|
|
|
56
58
|
app.command()(main)
|
|
57
59
|
|
dataops_cli/cli/table.py
CHANGED
|
@@ -6,10 +6,18 @@ from rich.table import Table
|
|
|
6
6
|
|
|
7
7
|
from dataops_cli.cli.utils import render_table
|
|
8
8
|
from dataops_cli.exceptions import DataOpsError
|
|
9
|
-
from dataops_cli.schems
|
|
10
|
-
|
|
9
|
+
from dataops_cli.schems import (
|
|
10
|
+
DataBaseColumnReference,
|
|
11
|
+
DataBaseColumnReferenceValue,
|
|
12
|
+
DataBaseColumnTypeExternal,
|
|
13
|
+
PageParam,
|
|
14
|
+
SqlQueryParam,
|
|
15
|
+
)
|
|
16
|
+
from dataops_cli.sdk import (
|
|
17
|
+
release_list_update,
|
|
11
18
|
service_count_table_by_code,
|
|
12
19
|
service_count_table_by_name,
|
|
20
|
+
service_get_dict_detail_by_name,
|
|
13
21
|
service_get_table_data_by_code,
|
|
14
22
|
service_get_table_data_by_name,
|
|
15
23
|
service_get_table_detail_by_code,
|
|
@@ -19,6 +27,10 @@ from dataops_cli.sdk.table import (
|
|
|
19
27
|
from dataops_cli.utils import filter_nodes_by_pattern
|
|
20
28
|
|
|
21
29
|
table_typer = typer.Typer(name="table", help="Manage table.", no_args_is_help=True)
|
|
30
|
+
config_typer = typer.Typer(name="update", help="变更", no_args_is_help=True)
|
|
31
|
+
table_typer.add_typer(config_typer)
|
|
32
|
+
column_typer = typer.Typer(name="column", help="列变更", no_args_is_help=True)
|
|
33
|
+
config_typer.add_typer(column_typer)
|
|
22
34
|
|
|
23
35
|
|
|
24
36
|
@table_typer.command("list")
|
|
@@ -208,3 +220,74 @@ def get_table_data(
|
|
|
208
220
|
print("未查询到数据")
|
|
209
221
|
return
|
|
210
222
|
print(render_table(data))
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
@column_typer.command("base", no_args_is_help=True)
|
|
226
|
+
def set_column_config(
|
|
227
|
+
datasource: Annotated[str, typer.Argument(help="编数据源")],
|
|
228
|
+
name: Annotated[Optional[str], typer.Argument(help="表名")],
|
|
229
|
+
column: Annotated[str, typer.Argument(help="列名")],
|
|
230
|
+
title: Annotated[str | None, typer.Option(help="中文名称")] = None,
|
|
231
|
+
pk: Annotated[bool | None, typer.Option(help="主键")] = None,
|
|
232
|
+
nullable: Annotated[bool | None, typer.Option(help="是否可为空")] = None,
|
|
233
|
+
labelKey: Annotated[bool | None, typer.Option(help="名称键")] = None,
|
|
234
|
+
remark: Annotated[str | None, typer.Option(help="备注")] = None,
|
|
235
|
+
) -> None:
|
|
236
|
+
"""修改列基础配置"""
|
|
237
|
+
meta = service_get_table_detail_by_name(datasource, name)
|
|
238
|
+
column = next(filter(lambda c: c.name == column, meta.data.columns))
|
|
239
|
+
if title:
|
|
240
|
+
column.title = title
|
|
241
|
+
if pk is not None:
|
|
242
|
+
column.pk = pk
|
|
243
|
+
if nullable is not None:
|
|
244
|
+
column.nullable = nullable
|
|
245
|
+
if labelKey:
|
|
246
|
+
column.labelKey = labelKey
|
|
247
|
+
if remark:
|
|
248
|
+
column.remark = remark
|
|
249
|
+
result = release_list_update(meta)
|
|
250
|
+
typer.echo(f"修改 {datasource} {name} {column.name} 完成")
|
|
251
|
+
|
|
252
|
+
|
|
253
|
+
@column_typer.command("dict", no_args_is_help=True)
|
|
254
|
+
def set_column_dict_config(
|
|
255
|
+
datasource: Annotated[str, typer.Argument(help="编数据源")],
|
|
256
|
+
name: Annotated[Optional[str], typer.Argument(help="表名")],
|
|
257
|
+
column: Annotated[str, typer.Argument(help="列名")],
|
|
258
|
+
dict_name: Annotated[str, typer.Option("--dict", help="字典名称")] = None,
|
|
259
|
+
) -> None:
|
|
260
|
+
"""设置列字典关系配置"""
|
|
261
|
+
table_meta = service_get_table_detail_by_name(datasource, name)
|
|
262
|
+
column_item = next(filter(lambda c: c.name == column, table_meta.data.columns))
|
|
263
|
+
dict_meta = service_get_dict_detail_by_name(datasource, dict_name)
|
|
264
|
+
column_item.type = "dict"
|
|
265
|
+
column_item.typeExt = DataBaseColumnTypeExternal(
|
|
266
|
+
ref__dict=DataBaseColumnReference(type="dict", code=dict_meta.code)
|
|
267
|
+
)
|
|
268
|
+
result = release_list_update(table_meta)
|
|
269
|
+
typer.echo(f"修改 {datasource} {name} {column.name} 完成")
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
@column_typer.command("relation", no_args_is_help=True)
|
|
273
|
+
def set_column_dict_config(
|
|
274
|
+
datasource: Annotated[str, typer.Argument(help="编数据源")],
|
|
275
|
+
name: Annotated[Optional[str], typer.Argument(help="表名")],
|
|
276
|
+
column: Annotated[str, typer.Argument(help="列名")],
|
|
277
|
+
r_name: Annotated[str, typer.Option(help="目标表名")] = None,
|
|
278
|
+
r_col_name: Annotated[str, typer.Option(help="目标列名")] = None,
|
|
279
|
+
) -> None:
|
|
280
|
+
"""设置字段关系配置"""
|
|
281
|
+
table_meta = service_get_table_detail_by_name(datasource, name)
|
|
282
|
+
column_item = next(filter(lambda c: c.name == column, table_meta.data.columns))
|
|
283
|
+
dst_table_meta = service_get_table_detail_by_name(datasource, r_name)
|
|
284
|
+
dst_column_item = next(filter(lambda c: c.name == r_col_name, dst_table_meta.data.columns))
|
|
285
|
+
column_item.type = "relation"
|
|
286
|
+
column_item.typeExt = DataBaseColumnTypeExternal(
|
|
287
|
+
ref__table=DataBaseColumnReference(type="table", code=dst_table_meta.code),
|
|
288
|
+
ref__valueField=DataBaseColumnReferenceValue(
|
|
289
|
+
type="table", code=dst_table_meta.code, subtype="column", subcode=dst_column_item.id
|
|
290
|
+
),
|
|
291
|
+
)
|
|
292
|
+
result = release_list_update(table_meta)
|
|
293
|
+
typer.echo(f"修改 {datasource} {name} {column.name} 完成")
|
dataops_cli/schems/__init__.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from .data_table import DataTableData, MetaDataTable
|
|
2
|
-
from .datasource import
|
|
2
|
+
from .datasource import DataDataSource
|
|
3
|
+
from .dict_ import DataDict, DictItem
|
|
3
4
|
from .enums import InnerMetaType, MetaType
|
|
4
5
|
from .group import GroupNode
|
|
5
6
|
from .meta import (
|
|
@@ -14,7 +15,13 @@ from .meta import (
|
|
|
14
15
|
)
|
|
15
16
|
from .query import PageParam, SqlCondition, SqlQueryParam, SqlSort
|
|
16
17
|
from .report import ReportMeta, ReportMetaData
|
|
17
|
-
from .table import
|
|
18
|
+
from .table import (
|
|
19
|
+
ColumnItem,
|
|
20
|
+
DataBaseColumnReference,
|
|
21
|
+
DataBaseColumnReferenceValue,
|
|
22
|
+
DataBaseColumnTypeExternal,
|
|
23
|
+
DataDataBase,
|
|
24
|
+
)
|
|
18
25
|
from .user import Application, UserInfo
|
|
19
26
|
from .widget import WidgetMeta
|
|
20
27
|
from .workflow import DataWorkflow, MetaWorkflow
|
dataops_cli/schems/data_table.py
CHANGED
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
|
|
7
7
|
from __future__ import annotations
|
|
8
8
|
|
|
9
|
-
from enum import StrEnum
|
|
10
9
|
from typing import Annotated, Any, Literal, Mapping
|
|
11
10
|
|
|
12
11
|
from pydantic import (
|
|
@@ -18,46 +17,9 @@ from pydantic import (
|
|
|
18
17
|
JsonValue,
|
|
19
18
|
)
|
|
20
19
|
|
|
21
|
-
from .
|
|
22
|
-
|
|
23
|
-
# ---------------------------------------------------------------------------
|
|
24
|
-
# Field Types & Expressions
|
|
25
|
-
# ---------------------------------------------------------------------------
|
|
26
|
-
|
|
20
|
+
from dataops_cli.schems.enums import ColumnType, SqlExpression
|
|
27
21
|
|
|
28
|
-
|
|
29
|
-
"""字段类型枚举."""
|
|
30
|
-
|
|
31
|
-
TEXT = "text"
|
|
32
|
-
NUMBER = "number"
|
|
33
|
-
DATE = "date"
|
|
34
|
-
DATETIME = "datetime"
|
|
35
|
-
SELECT = "select"
|
|
36
|
-
MULTI_SELECT = "multiSelect"
|
|
37
|
-
RELATION = "relation"
|
|
38
|
-
DICT = "dict"
|
|
39
|
-
USER = "user"
|
|
40
|
-
FILE = "file"
|
|
41
|
-
SUBTABLE = "subtable"
|
|
42
|
-
STRING = "string"
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
class SqlExpression(StrEnum):
|
|
46
|
-
"""过滤表达式枚举."""
|
|
47
|
-
|
|
48
|
-
EQ = "eq"
|
|
49
|
-
NE = "ne"
|
|
50
|
-
GT = "gt"
|
|
51
|
-
GE = "ge"
|
|
52
|
-
LT = "lt"
|
|
53
|
-
LE = "le"
|
|
54
|
-
LIKE = "like"
|
|
55
|
-
NOT_LIKE = "notlike"
|
|
56
|
-
IN = "in"
|
|
57
|
-
NOT_IN = "notin"
|
|
58
|
-
BETWEEN = "between"
|
|
59
|
-
IS_NULL = "isnull"
|
|
60
|
-
IS_NOT_NULL = "isnotnull"
|
|
22
|
+
from .meta import Meta, MetaCreate
|
|
61
23
|
|
|
62
24
|
|
|
63
25
|
def insert_dict_by_none(v):
|
|
@@ -285,7 +247,7 @@ class DataTableField(BaseModel):
|
|
|
285
247
|
id: Annotated[str | None, Field(description="字段唯一标识 (UUID)", exclude=True)] = None
|
|
286
248
|
|
|
287
249
|
dbName: Annotated[str, Field(description="字段名称/列名 (存储在数据库中的名称)")]
|
|
288
|
-
dbType: Annotated[
|
|
250
|
+
dbType: Annotated[ColumnType, Field(description="字段类型")]
|
|
289
251
|
|
|
290
252
|
title: Annotated[str | None, Field(description="显示标题")]
|
|
291
253
|
name: Annotated[str, Field(description="字段名称/列名 (前端显示的名称)")]
|
dataops_cli/schems/datasource.py
CHANGED
|
@@ -1,59 +1,25 @@
|
|
|
1
1
|
from typing import Annotated
|
|
2
2
|
|
|
3
|
-
from pydantic import BaseModel,
|
|
3
|
+
from pydantic import BaseModel, BeforeValidator, Field
|
|
4
4
|
|
|
5
|
-
from dataops_cli.schems.
|
|
5
|
+
from dataops_cli.schems.enums import DataSourceType
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
def str_to_number(v: str):
|
|
9
|
+
assert v.isnumeric(), "must be number"
|
|
10
|
+
return int(v)
|
|
11
11
|
|
|
12
12
|
|
|
13
|
-
class
|
|
14
|
-
|
|
15
|
-
subcode: Annotated[str, Field(description="引用子编码")]
|
|
13
|
+
class DataDataSource(BaseModel):
|
|
14
|
+
"""Data source"""
|
|
16
15
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
ref__table: Annotated[
|
|
21
|
-
DataSourceColumnReference | None, Field(description="外部类型表", exclude=True)
|
|
22
|
-
] = None
|
|
23
|
-
ref__valueField: Annotated[
|
|
24
|
-
DataSourceColumnReferenceValue | None, Field(description="外部类型值字段")
|
|
25
|
-
] = None
|
|
26
|
-
ref__displayField: Annotated[
|
|
27
|
-
DataSourceColumnReferenceValue | None,
|
|
28
|
-
Field(description="外部类型显示字段", exclude=True),
|
|
29
|
-
] = None
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
class DataSourceColumn(BaseModel):
|
|
33
|
-
id: Annotated[str, Field(description="列ID", exclude=True)]
|
|
34
|
-
name: Annotated[str, Field(description="列名")]
|
|
35
|
-
title: Annotated[str, Field(description="列标题")]
|
|
36
|
-
dbType: Annotated[str, Field(description="数据库类型")]
|
|
37
|
-
nullable: Annotated[bool, Field(description="是否可为空")] = True
|
|
38
|
-
length: Annotated[int | None, Field(description="长度", exclude=True)] = None
|
|
39
|
-
pk: Annotated[bool, Field(description="是否主键")] = False
|
|
40
|
-
labelKey: Annotated[bool, Field(description="是否标签键")] = False
|
|
41
|
-
type: Annotated[str | None, Field(description="类型", exclude=True)] = None
|
|
42
|
-
typeExt: Annotated[
|
|
43
|
-
DataSourceColumnTypeExternal | None, Field(description="类型扩展", exclude=True)
|
|
44
|
-
] = None
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
class DataSourceDDL(BaseModel):
|
|
48
|
-
"""Data source DDL"""
|
|
49
|
-
|
|
50
|
-
columns: Annotated[list[DataSourceColumn], Field(description="列信息", default_factory=list)]
|
|
51
|
-
indexes: Annotated[
|
|
52
|
-
list[dict[str, JsonValue]], Field(description="索引信息", default_factory=list)
|
|
16
|
+
type: Annotated[DataSourceType, Field(description="数据源类型")] = DataSourceType.MYSQL
|
|
17
|
+
port: Annotated[
|
|
18
|
+
int, BeforeValidator(str_to_number), Field(description="数据源端口", le=65535, gt=0)
|
|
53
19
|
]
|
|
20
|
+
ip: Annotated[str, Field(description="数据源主机")]
|
|
21
|
+
username: Annotated[str, Field(description="数据源用户名")]
|
|
22
|
+
password: Annotated[str, Field(description="数据源密码")]
|
|
23
|
+
database: Annotated[str, Field(description="数据库名称")]
|
|
54
24
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
class MetaDataSourceDDL(Meta[DataSourceDDL]):
|
|
59
|
-
"""Meta data source DDL"""
|
|
25
|
+
category: Annotated[str, Field(description="数据源分类")] = "database"
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from typing import Annotated
|
|
2
|
+
|
|
3
|
+
from pydantic import BaseModel, Field
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class DictItem(BaseModel):
|
|
7
|
+
id: Annotated[str, Field(description="id", exclude=True)]
|
|
8
|
+
value: Annotated[str | int, Field(description="值")]
|
|
9
|
+
label: Annotated[str, Field(description="名")]
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class DataDict(BaseModel):
|
|
13
|
+
options: Annotated[list[DictItem], Field(description="字典数据", default_factory=list)]
|