data-ops-cli 0.3.4__tar.gz → 0.3.6__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.
Files changed (35) hide show
  1. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/PKG-INFO +2 -2
  2. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/pyproject.toml +1 -1
  3. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/data_ops_cli.egg-info/PKG-INFO +2 -2
  4. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/data_ops_cli.egg-info/requires.txt +1 -1
  5. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/dataops_cli/__init__.py +1 -1
  6. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/dataops_cli/cli/alarm.py +251 -22
  7. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/dataops_cli/cli/api.py +1 -1
  8. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/dataops_cli/cli/auth.py +4 -2
  9. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/dataops_cli/cli/data_table.py +14 -13
  10. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/dataops_cli/cli/dataset.py +3 -3
  11. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/dataops_cli/cli/datasource.py +1 -4
  12. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/dataops_cli/cli/dict_.py +4 -4
  13. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/dataops_cli/cli/metrics.py +3 -3
  14. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/dataops_cli/cli/report.py +3 -3
  15. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/dataops_cli/cli/skill.py +26 -48
  16. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/dataops_cli/cli/table.py +41 -31
  17. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/dataops_cli/cli/widget.py +1 -1
  18. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/dataops_cli/cli/workflow.py +1 -1
  19. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/setup.cfg +0 -0
  20. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/data_ops_cli.egg-info/SOURCES.txt +0 -0
  21. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/data_ops_cli.egg-info/dependency_links.txt +0 -0
  22. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/data_ops_cli.egg-info/entry_points.txt +0 -0
  23. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/data_ops_cli.egg-info/top_level.txt +0 -0
  24. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/dataops_cli/_compat.py +0 -0
  25. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/dataops_cli/cli/__init__.py +0 -0
  26. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/dataops_cli/cli/factory.py +0 -0
  27. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/dataops_cli/cli/hazard.py +0 -0
  28. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/dataops_cli/cli/ref.py +0 -0
  29. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/dataops_cli/cli/utils.py +0 -0
  30. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/dataops_cli/exceptions.py +0 -0
  31. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/dataops_cli/runner.py +0 -0
  32. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/dataops_cli/schems.py +0 -0
  33. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/dataops_cli/sdk.py +0 -0
  34. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/dataops_cli/session.py +0 -0
  35. {data_ops_cli-0.3.4 → data_ops_cli-0.3.6}/src/dataops_cli/utils.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: data-ops-cli
3
- Version: 0.3.4
3
+ Version: 0.3.6
4
4
  Summary: Command-line wrapper around dataops_sdk for the DataOps platform.
5
5
  Requires-Python: >=3.11
6
- Requires-Dist: dataops-sdk[runner]>=0.3.4
6
+ Requires-Dist: dataops-sdk[runner]>=0.3.6
7
7
  Requires-Dist: typer
8
8
  Requires-Dist: rich
9
9
  Provides-Extra: dev
@@ -8,7 +8,7 @@ dynamic = ["version"]
8
8
  description = "Command-line wrapper around dataops_sdk for the DataOps platform."
9
9
  requires-python = ">=3.11"
10
10
  dependencies = [
11
- "dataops-sdk[runner]>=0.3.4",
11
+ "dataops-sdk[runner]>=0.3.6",
12
12
  "typer",
13
13
  "rich",
14
14
  ]
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: data-ops-cli
3
- Version: 0.3.4
3
+ Version: 0.3.6
4
4
  Summary: Command-line wrapper around dataops_sdk for the DataOps platform.
5
5
  Requires-Python: >=3.11
6
- Requires-Dist: dataops-sdk[runner]>=0.3.4
6
+ Requires-Dist: dataops-sdk[runner]>=0.3.6
7
7
  Requires-Dist: typer
8
8
  Requires-Dist: rich
9
9
  Provides-Extra: dev
@@ -1,4 +1,4 @@
1
- dataops-sdk[runner]>=0.3.4
1
+ dataops-sdk[runner]>=0.3.6
2
2
  typer
3
3
  rich
4
4
 
@@ -14,4 +14,4 @@ groups command modules under :mod:`dataops_cli.cli` and re-exports the package
14
14
  removed in ``dataops_cli`` 1.0.
15
15
  """
16
16
 
17
- __version__ = "0.3.4"
17
+ __version__ = "0.3.6"
@@ -11,7 +11,6 @@ from typing import Annotated, Any
11
11
 
12
12
  import typer
13
13
  from dataops_sdk.exceptions import DataOpsError
14
- from dataops_sdk.schemas.query import SqlQueryParam
15
14
  from dataops_sdk.services.alarm import (
16
15
  service_count_alarm_action,
17
16
  service_count_alarm_rule_matches,
@@ -19,10 +18,18 @@ from dataops_sdk.services.alarm import (
19
18
  service_count_alarm_specs,
20
19
  service_find_alarm_table_data,
21
20
  service_find_meta_by_codes,
21
+ service_get_alarm_action_detail,
22
+ service_get_alarm_builtin_function_detail,
23
+ service_get_alarm_preprocess_detail,
24
+ service_get_alarm_rule_detail,
22
25
  service_get_alarm_rule_enums,
26
+ service_get_alarm_rule_type_detail,
27
+ service_get_alarm_spec_detail,
23
28
  service_get_alarm_table_columns,
24
29
  service_get_rel_table_columns,
25
30
  service_list_alarm_action,
31
+ service_list_alarm_builtin_functions,
32
+ service_list_alarm_preprocess,
26
33
  service_list_alarm_rule_matches,
27
34
  service_list_alarm_rules,
28
35
  service_list_alarm_specs,
@@ -39,13 +46,21 @@ from dataops_cli.cli.utils import print_list
39
46
 
40
47
  alarm_typer = typer.Typer(name="alarm", help="告警规则配置", no_args_is_help=True)
41
48
  alarm_rule_typer = typer.Typer(name="rule", help="告警规则命令", no_args_is_help=True)
49
+ alarm_rule_type_typer = typer.Typer(name="type", help="告警规则类型命令", no_args_is_help=True)
42
50
  alarm_spec_typer = typer.Typer(name="spec", help="告警专业命令", no_args_is_help=True)
43
51
  alarm_action_typer = typer.Typer(name="action", help="告警动作命令", no_args_is_help=True)
52
+ alarm_preprocess_typer = typer.Typer(name="preprocess", help="预处理脚本命令", no_args_is_help=True)
53
+ alarm_builtin_function_typer = typer.Typer(
54
+ name="builtin-function", help="内置函数命令", no_args_is_help=True
55
+ )
44
56
  rule_match_typer = typer.Typer(name="match", help="规则匹配命令", no_args_is_help=True)
45
57
  alarm_typer.add_typer(alarm_rule_typer, no_args_is_help=True)
46
58
  alarm_typer.add_typer(alarm_spec_typer, no_args_is_help=True)
59
+ alarm_rule_typer.add_typer(alarm_rule_type_typer, no_args_is_help=True)
47
60
  alarm_rule_typer.add_typer(rule_match_typer, no_args_is_help=True)
48
61
  alarm_typer.add_typer(alarm_action_typer, no_args_is_help=True)
62
+ alarm_typer.add_typer(alarm_preprocess_typer, no_args_is_help=True)
63
+ alarm_typer.add_typer(alarm_builtin_function_typer, no_args_is_help=True)
49
64
 
50
65
 
51
66
  def _safe_str(value: Any) -> str:
@@ -87,6 +102,155 @@ def _print_column_list(data: Any) -> None:
87
102
  print(to_json(columns).decode("utf-8"))
88
103
 
89
104
 
105
+ def _print_alarm_detail(detail: Any, title: str, simplify: bool = False) -> None:
106
+ """渲染告警详情的主体、data 和参数。"""
107
+ console = Console(no_color=True)
108
+ meta = detail.meta
109
+ basic_table = Table("字段", "值", title=title, show_header=False)
110
+ for field in ("code", "title", "type", "remark", "createUser", "lastModifyTime"):
111
+ value = getattr(meta, field, None)
112
+ if value is not None:
113
+ basic_table.add_row(field, _safe_str(value))
114
+ console.print(basic_table)
115
+
116
+ data = meta.data or {}
117
+ if hasattr(data, "model_dump"):
118
+ data = data.model_dump(mode="json")
119
+ if isinstance(data, dict):
120
+ data_table = Table("data 字段", "值", title="详情数据", show_header=False)
121
+ for key, value in data.items():
122
+ if simplify and key.lower() in {"script", "scriptcontent", "script_content"}:
123
+ continue
124
+ data_table.add_row(str(key), _safe_str(value))
125
+ if data_table.row_count:
126
+ console.print(data_table)
127
+
128
+ if detail.params:
129
+ params_table = Table("参数", "值", title="Meta 参数", show_header=False)
130
+ for key, value in detail.params.items():
131
+ params_table.add_row(str(key), _safe_str(value))
132
+ console.print(params_table)
133
+
134
+
135
+ def _handle_alarm_detail(detail_service, code: str, title: str, simplify: bool) -> None:
136
+ """统一处理详情 service 的错误和终端输出。"""
137
+ try:
138
+ detail = detail_service(code)
139
+ except DataOpsError as e:
140
+ typer.echo(f"错误: {e.message}")
141
+ raise typer.Exit(code=1) from None
142
+ _print_alarm_detail(detail, title, simplify)
143
+
144
+
145
+ @alarm_preprocess_typer.command("list", help="查询预处理脚本")
146
+ def list_alarm_preprocess(
147
+ spec_type: Annotated[
148
+ list[str] | None, typer.Option("--spec-type", help="关联专业编码,可重复传入")
149
+ ] = None,
150
+ enabled: Annotated[
151
+ list[str] | None, typer.Option("--enabled", help="启用状态值 1/0,可重复传入")
152
+ ] = None,
153
+ page_num: Annotated[int, typer.Option("-n", "--page-num", "--page", help="页码")] = 0,
154
+ page_size: Annotated[int, typer.Option("-s", "--page-size", "--size", help="每页大小")] = 20,
155
+ query: Annotated[str | None, typer.Option("-q", "--query", help="脚本名称关键词")] = None,
156
+ ) -> None:
157
+ """查询预处理脚本列表。"""
158
+ try:
159
+ rows = service_list_alarm_preprocess(
160
+ page_num,
161
+ page_size,
162
+ query,
163
+ spec_type or [],
164
+ enabled or [],
165
+ )
166
+ except DataOpsError as e:
167
+ typer.echo(f"错误: {e.message}")
168
+ raise typer.Exit(code=1) from None
169
+
170
+ if not rows:
171
+ print("未查询到预处理脚本")
172
+ return
173
+ print_list(
174
+ ["脚本编码", "脚本名称", "关联专业", "脚本说明", "启用状态", "创建人", "创建时间"],
175
+ [
176
+ [
177
+ row.CODE,
178
+ row.TITLE,
179
+ row.N_SPEC_TYPE,
180
+ row.DESCRIPTION,
181
+ row.IS_ENABLED,
182
+ row.CREATE_USER,
183
+ row.CREATE_TIME,
184
+ ]
185
+ for row in rows
186
+ ],
187
+ )
188
+
189
+
190
+ @alarm_preprocess_typer.command("detail", no_args_is_help=True)
191
+ def get_alarm_preprocess_detail(
192
+ code: Annotated[str, typer.Argument(help="预处理脚本编码")],
193
+ simplify: Annotated[bool, typer.Option("-s", "--simplify", help="隐藏脚本正文")] = False,
194
+ ) -> None:
195
+ """按编码查询预处理脚本详情。"""
196
+ _handle_alarm_detail(
197
+ service_get_alarm_preprocess_detail,
198
+ code,
199
+ "预处理脚本详情",
200
+ simplify,
201
+ )
202
+
203
+
204
+ @alarm_builtin_function_typer.command("list", help="查询内置函数")
205
+ def list_alarm_builtin_functions(
206
+ enabled: Annotated[
207
+ list[str] | None, typer.Option("--enabled", help="启用状态值 1/0,可重复传入")
208
+ ] = None,
209
+ page_num: Annotated[int, typer.Option("-n", "--page-num", "--page", help="页码")] = 0,
210
+ page_size: Annotated[int, typer.Option("-s", "--page-size", "--size", help="每页大小")] = 20,
211
+ query: Annotated[str | None, typer.Option("-q", "--query", help="函数名称关键词")] = None,
212
+ ) -> None:
213
+ """查询内置函数列表。"""
214
+ try:
215
+ rows = service_list_alarm_builtin_functions(page_num, page_size, query, enabled or [])
216
+ except DataOpsError as e:
217
+ typer.echo(f"错误: {e.message}")
218
+ raise typer.Exit(code=1) from None
219
+
220
+ if not rows:
221
+ print("未查询到内置函数")
222
+ return
223
+ print_list(
224
+ ["函数编码", "函数名称", "类全路径", "备注", "启用状态", "创建人", "创建时间"],
225
+ [
226
+ [
227
+ row.CODE,
228
+ row.TITLE,
229
+ row.CLAZZ,
230
+ row.REMARK,
231
+ row.IS_ENABLED,
232
+ row.CREATE_USER,
233
+ row.CREATE_TIME,
234
+ ]
235
+ for row in rows
236
+ ],
237
+ )
238
+
239
+
240
+ @alarm_builtin_function_typer.command("detail", no_args_is_help=True)
241
+ def get_alarm_builtin_function_detail(
242
+ code: Annotated[str, typer.Argument(help="内置函数编码")],
243
+ simplify: Annotated[bool, typer.Option("-s", "--simplify", help="隐藏函数脚本")] = False,
244
+ ) -> None:
245
+ """按编码查询内置函数详情。"""
246
+ _handle_alarm_detail(
247
+ service_get_alarm_builtin_function_detail,
248
+ code,
249
+ "内置函数详情",
250
+ simplify,
251
+ )
252
+
253
+
90
254
  @rule_match_typer.command("count", help="查询告警匹配规则数量")
91
255
  def count_alarm_rules_match(
92
256
  spec: Annotated[list[str], typer.Option(help="专业值", default_factory=list)],
@@ -116,8 +280,8 @@ def count_alarm_rules_match(
116
280
  @rule_match_typer.command("list", help="查询告警匹配规则")
117
281
  def list_alarm_rules_match(
118
282
  spec: Annotated[list[str], typer.Option(help="专业值", default_factory=list)],
119
- page_num: Annotated[int, typer.Option("-n", "--page-num", help="页码")] = 0,
120
- page_size: Annotated[int, typer.Option("-s", "--page-size", help="每页大小")] = 20,
283
+ page_num: Annotated[int, typer.Option("-n", "--page-num", "--page", help="页码")] = 0,
284
+ page_size: Annotated[int, typer.Option("-s", "--page-size", "--size", help="每页大小")] = 20,
121
285
  query: Annotated[str | None, typer.Option("-q", "--query", help="搜索关键字")] = None,
122
286
  enabled: Annotated[bool | None, typer.Option(help="启用状态")] = None,
123
287
  ):
@@ -169,10 +333,53 @@ def list_alarm_rules_match(
169
333
  )
170
334
 
171
335
 
336
+ @alarm_rule_typer.command("list", help="查询告警匹配规则")
337
+ def list_alarm_rules(
338
+ spec: Annotated[list[str], typer.Option(help="专业值", default_factory=list)],
339
+ page_num: Annotated[int, typer.Option("-n", "--page-num", "--page", help="页码")] = 0,
340
+ page_size: Annotated[int, typer.Option("-s", "--page-size", "--size", help="每页大小")] = 20,
341
+ query: Annotated[str | None, typer.Option("-q", "--query", help="搜索关键字")] = None,
342
+ enabled: Annotated[bool | None, typer.Option(help="启用状态")] = None,
343
+ ) -> None:
344
+ """查询告警匹配规则列表。
345
+
346
+ 这是前端 ``pages/alarm/rule`` 对应的 canonical 命令;旧的
347
+ ``alarm rule match list`` 仍保留作为兼容入口。
348
+ """
349
+ list_alarm_rules_match(spec, page_num, page_size, query, enabled)
350
+
351
+
352
+ @alarm_rule_typer.command("detail", no_args_is_help=True)
353
+ def get_alarm_rule_detail(
354
+ code: Annotated[str, typer.Argument(help="告警匹配规则编码")],
355
+ simplify: Annotated[bool, typer.Option("-s", "--simplify", help="简化详情输出")] = False,
356
+ ) -> None:
357
+ """按编码查询告警匹配规则基础详情。"""
358
+ _handle_alarm_detail(service_get_alarm_rule_detail, code, "告警匹配规则详情", simplify)
359
+
360
+
361
+ @alarm_rule_typer.command("count", help="兼容查询告警规则类型数量")
362
+ def count_alarm_rules_compat(
363
+ query: Annotated[str | None, typer.Option("-q", "--query", help="搜索关键字")] = None,
364
+ enabled: Annotated[bool | None, typer.Option(help="启用状态")] = None,
365
+ ) -> None:
366
+ """兼容保留的原规则类型数量命令。
367
+
368
+ 规则类型的 canonical 列表命令是 ``alarm rule type list``;匹配规则数量
369
+ 仍使用 ``alarm rule match count``。
370
+ """
371
+ try:
372
+ total = service_count_alarm_rules(query, enabled)
373
+ except DataOpsError as e:
374
+ typer.echo(f"错误: {e.message}")
375
+ raise typer.Exit(code=1) from None
376
+ print(total)
377
+
378
+
172
379
  @alarm_spec_typer.command("list", help="查询告警专业")
173
380
  def list_alarm_specs(
174
- page_num: Annotated[int, typer.Option("-n", "--page-num", help="页码")] = 0,
175
- page_size: Annotated[int, typer.Option("-s", "--page-size", help="每页大小")] = 20,
381
+ page_num: Annotated[int, typer.Option("-n", "--page-num", "--page", help="页码")] = 0,
382
+ page_size: Annotated[int, typer.Option("-s", "--page-size", "--size", help="每页大小")] = 20,
176
383
  query: Annotated[str | None, typer.Option("-q", "--query", help="搜索关键字")] = None,
177
384
  active: Annotated[bool | None, typer.Option(help="启用状态")] = None,
178
385
  ):
@@ -189,12 +396,7 @@ def list_alarm_specs(
189
396
  Examples:
190
397
  >>> data-ops-cli alarm spec list -q "网元"
191
398
  """
192
- query_param = SqlQueryParam()
193
- if active is not None:
194
- query_param.varMap["isEnabled"] = "1" if active else "0"
195
- if query:
196
- query_param.add_like("title", query, "mrl")
197
- group_nodes = service_list_alarm_specs(page_num, page_size, query_param)
399
+ group_nodes = service_list_alarm_specs(page_num, page_size, query, active)
198
400
 
199
401
  print_list(
200
402
  ["专业名称", "值", "行业", "启用状态", "创建人", "更新时间"],
@@ -212,6 +414,15 @@ def list_alarm_specs(
212
414
  )
213
415
 
214
416
 
417
+ @alarm_spec_typer.command("detail", no_args_is_help=True)
418
+ def get_alarm_spec_detail(
419
+ code: Annotated[str, typer.Argument(help="告警专业编码")],
420
+ simplify: Annotated[bool, typer.Option("-s", "--simplify", help="简化详情输出")] = False,
421
+ ) -> None:
422
+ """按编码查询告警专业详情。"""
423
+ _handle_alarm_detail(service_get_alarm_spec_detail, code, "告警专业详情", simplify)
424
+
425
+
215
426
  @alarm_spec_typer.command("count", help="查询告警专业数量")
216
427
  def count_alarm_specs(
217
428
  query: Annotated[str | None, typer.Option("-q", "--query", help="搜索关键字")] = None,
@@ -230,14 +441,14 @@ def count_alarm_specs(
230
441
  print(total)
231
442
 
232
443
 
233
- @alarm_rule_typer.command("list", help="查询告警规则")
234
- def list_alarm_rules(
235
- page_num: Annotated[int, typer.Option("-n", "--page-num", help="页码")] = 0,
236
- page_size: Annotated[int, typer.Option("-s", "--page-size", help="每页大小")] = 20,
444
+ @alarm_rule_type_typer.command("list", help="查询告警规则类型")
445
+ def list_alarm_rule_types(
446
+ page_num: Annotated[int, typer.Option("-n", "--page-num", "--page", help="页码")] = 0,
447
+ page_size: Annotated[int, typer.Option("-s", "--page-size", "--size", help="每页大小")] = 20,
237
448
  query: Annotated[str | None, typer.Option("-q", "--query", help="搜索关键字")] = None,
238
449
  enabled: Annotated[bool | None, typer.Option(help="启用状态")] = None,
239
450
  ):
240
- """查询告警规则列表。
451
+ """查询告警规则类型列表。
241
452
 
242
453
  按关键字与启用状态过滤告警规则,并以平面表格输出名称、值与启用状态。
243
454
 
@@ -248,7 +459,7 @@ def list_alarm_rules(
248
459
  enabled: 可选启用状态过滤。
249
460
 
250
461
  Examples:
251
- >>> data-ops-cli alarm rule list -q "电压"
462
+ >>> data-ops-cli alarm rule type list -q "电压"
252
463
  """
253
464
  group_nodes = service_list_alarm_rules(page_num, page_size, query, enabled)
254
465
 
@@ -267,8 +478,17 @@ def list_alarm_rules(
267
478
  )
268
479
 
269
480
 
270
- @alarm_spec_typer.command("count", help="查询告警规则数量")
271
- def count_alarm_specs(
481
+ @alarm_rule_type_typer.command("detail", no_args_is_help=True)
482
+ def get_alarm_rule_type_detail(
483
+ code: Annotated[str, typer.Argument(help="告警规则类型编码")],
484
+ simplify: Annotated[bool, typer.Option("-s", "--simplify", help="简化详情输出")] = False,
485
+ ) -> None:
486
+ """按编码查询告警规则类型详情。"""
487
+ _handle_alarm_detail(service_get_alarm_rule_type_detail, code, "告警规则类型详情", simplify)
488
+
489
+
490
+ @alarm_rule_type_typer.command("count", help="查询告警规则类型数量")
491
+ def count_alarm_rule_types(
272
492
  query: Annotated[str | None, typer.Option("-q", "--query", help="搜索关键字")] = None,
273
493
  enabled: Annotated[bool | None, typer.Option(help="启用状态")] = None,
274
494
  ):
@@ -279,7 +499,7 @@ def count_alarm_specs(
279
499
  enabled: 可选启用状态过滤。
280
500
 
281
501
  Examples:
282
- >>> data-ops-cli alarm rule count
502
+ >>> data-ops-cli alarm rule type count
283
503
  """
284
504
  total = service_count_alarm_rules(query, enabled)
285
505
  print(total)
@@ -288,8 +508,8 @@ def count_alarm_specs(
288
508
  @alarm_action_typer.command("list", help="查询告警动作")
289
509
  def list_alarm_actions(
290
510
  rule: Annotated[list[str], typer.Option(help="专业值", default_factory=list)],
291
- page_num: Annotated[int, typer.Option("-n", "--page-num", help="页码")] = 0,
292
- page_size: Annotated[int, typer.Option("-s", "--page-size", help="每页大小")] = 20,
511
+ page_num: Annotated[int, typer.Option("-n", "--page-num", "--page", help="页码")] = 0,
512
+ page_size: Annotated[int, typer.Option("-s", "--page-size", "--size", help="每页大小")] = 20,
293
513
  query: Annotated[str | None, typer.Option("-q", "--query", help="搜索关键字")] = None,
294
514
  enabled: Annotated[bool | None, typer.Option(help="启用状态")] = None,
295
515
  ):
@@ -339,6 +559,15 @@ def list_alarm_actions(
339
559
  )
340
560
 
341
561
 
562
+ @alarm_action_typer.command("detail", no_args_is_help=True)
563
+ def get_alarm_action_detail(
564
+ code: Annotated[str, typer.Argument(help="告警动作编码")],
565
+ simplify: Annotated[bool, typer.Option("-s", "--simplify", help="简化详情输出")] = False,
566
+ ) -> None:
567
+ """按编码查询告警处置动作详情。"""
568
+ _handle_alarm_detail(service_get_alarm_action_detail, code, "告警处置动作详情", simplify)
569
+
570
+
342
571
  @alarm_action_typer.command("count", help="查询告警动作数量")
343
572
  def count_alarm_actions(
344
573
  rule: Annotated[list[str], typer.Option(help="专业值", default_factory=list)],
@@ -90,7 +90,7 @@ def list_apis(
90
90
 
91
91
  print_list(
92
92
  ["code", "title", "remark"],
93
- [[node.CODE, node.TITLE, _first_line(node.REMARK or "")] for node in group_nodes],
93
+ [[node.code, node.title, _first_line(node.remark or "")] for node in group_nodes],
94
94
  )
95
95
 
96
96
 
@@ -128,7 +128,9 @@ def logout() -> None:
128
128
 
129
129
 
130
130
  @application_typer.command("list")
131
- def application_list(query: Annotated[str | None, typer.Argument(help="关键字")] = None) -> None:
131
+ def application_list(
132
+ query: Annotated[str | None, typer.Option("-q", "--query", help="关键字")] = None,
133
+ ) -> None:
132
134
  """列出所有可用应用。
133
135
 
134
136
  显示当前用户可访问的所有应用列表,支持通过关键字过滤。
@@ -142,7 +144,7 @@ def application_list(query: Annotated[str | None, typer.Argument(help="关键字
142
144
  >>> data-ops-cli auth application list
143
145
 
144
146
  通过关键字过滤应用
145
- >>> data-ops-cli auth application list myapp
147
+ >>> data-ops-cli auth application list -q myapp
146
148
  """
147
149
  try:
148
150
  applications = service_list_applications(query)
@@ -68,8 +68,8 @@ def list_datatable(
68
68
  group_nodes = filter_nodes_by_pattern(group_nodes, query, include_digest=True)
69
69
 
70
70
  print_list(
71
- ["code", "title", "remark"],
72
- [[column.CODE, column.TITLE, column.REMARK] for column in group_nodes],
71
+ ["code", "name", "title", "remark"],
72
+ [[column.code, column.name, column.title, column.remark or ""] for column in group_nodes],
73
73
  )
74
74
 
75
75
 
@@ -106,23 +106,17 @@ def get_datatable_detail(
106
106
  typer.echo("错误: 未找到多维表格")
107
107
  raise typer.Exit(code=1) from None
108
108
 
109
- table = Table("field", "value", show_header=False)
110
- table.add_row("datasource", meta.data.model.datasource)
111
- table.add_row("引用类型", meta.data.model.ref_type)
112
- table.add_row("引用编码", meta.data.model.ref_code)
113
- table.add_row("引用表名", meta.data.model.table_name)
114
-
115
- console = Console(no_color=True)
116
- console.print(table)
109
+ print("ref-datasource ref-type ref-code ref-table-name")
110
+ print(meta.data.model.datasource, meta.data.model.ref_type, meta.data.model.ref_code, meta.data.model.table_name)
111
+ print()
117
112
 
118
113
  print_list(
119
- ["column(visable)", "type", "title", "visible"],
114
+ ["column(visable)", "type", "title"],
120
115
  [
121
116
  [
122
117
  field.name + f"({'√' if field.visible else 'x'})",
123
118
  field.type,
124
119
  field.title,
125
- field.visible,
126
120
  ]
127
121
  for field in meta.data.fields
128
122
  ],
@@ -260,8 +254,15 @@ def get_datatable_data(
260
254
  query_param: 可选 SqlQueryParam JSON。
261
255
 
262
256
  Examples:
263
- >>> data-ops-cli data_table data dt_code_001
257
+ 通过多为表格编码查询数据
258
+ >>> data-ops-cli data_table data <code>
259
+ 通过数据源和表名查询数据
260
+ >>> data-ops-cli data_table data <datasource> <name>
264
261
  """
262
+ if not name and not arg1.replace("_", "").replace("-", "").isnumeric():
263
+ print("输入参数错误 using `table detail <code>` or `table detail <datasource> <name>`")
264
+ raise typer.Exit(code=1) from None
265
+
265
266
  pp = PageParam(start=page_num * page_size, limit=page_size)
266
267
  qp = SqlQueryParam.model_validate_json(query_param) if query_param else SqlQueryParam()
267
268
 
@@ -26,7 +26,7 @@ dataset_typer = typer.Typer(name="dataset", help="Manage dataset.", no_args_is_h
26
26
 
27
27
  @dataset_typer.command("list")
28
28
  def list_dataset(
29
- query: Annotated[str | None, typer.Argument(help="名称关键字")] = None,
29
+ query: Annotated[str | None, typer.Option("-q", "--query", help="名称关键字")] = None,
30
30
  ) -> None:
31
31
  """列出所有数据集。
32
32
 
@@ -40,7 +40,7 @@ def list_dataset(
40
40
  >>> data-ops-cli dataset list
41
41
 
42
42
  # 按名称关键字过滤
43
- >>> data-ops-cli dataset list "HHI.*"
43
+ >>> data-ops-cli dataset list -q "HHI.*"
44
44
  """
45
45
  try:
46
46
  group_nodes = service_list_datasets()
@@ -53,7 +53,7 @@ def list_dataset(
53
53
 
54
54
  print_list(
55
55
  ["code", "name", "alias", "remark"],
56
- [[column.CODE, column.NAME, column.TITLE, column.REMARK] for column in group_nodes],
56
+ [[column.code, column.name, column.title, column.remark] for column in group_nodes],
57
57
  )
58
58
 
59
59
 
@@ -100,10 +100,7 @@ def list_datasource(
100
100
 
101
101
  print_list(
102
102
  ["name", "alias", "type", "remark"],
103
- [
104
- [column.NAME, column.TITLE, column.SUB_TYPE, column.REMARK or ""]
105
- for column in group_nodes
106
- ],
103
+ [[column.code, column.name, column.title, column.remark or ""] for column in group_nodes],
107
104
  )
108
105
 
109
106
 
@@ -22,7 +22,7 @@ dict_typer = typer.Typer(name="dict", help="Manage dict.", no_args_is_help=True)
22
22
  @dict_typer.command("list")
23
23
  def list_dict(
24
24
  datasource: Annotated[str, typer.Argument(help="数据源")],
25
- query: Annotated[str | None, typer.Argument(help="字典名称关键字")] = None,
25
+ query: Annotated[str | None, typer.Option("-q", "--query", help="字典名称关键字")] = None,
26
26
  ) -> None:
27
27
  """列出数据源中的字典列表。
28
28
 
@@ -37,10 +37,10 @@ def list_dict(
37
37
  >>> data-ops-cli dict list <datasource>
38
38
 
39
39
  # 列出数据源中名称包含 "user" 的字典
40
- >>> data-ops-cli dict list <datasource> user
40
+ >>> data-ops-cli dict list <datasource> -q user
41
41
 
42
42
  # 使用正则过滤字典名
43
- >>> data-ops-cli dict list <datasource> "^user_.*"
43
+ >>> data-ops-cli dict list <datasource> -q "^user_.*"
44
44
  """
45
45
  try:
46
46
  group_nodes = service_list_dicts(datasource)
@@ -57,7 +57,7 @@ def list_dict(
57
57
 
58
58
  print_list(
59
59
  ["code", "name", "alias"],
60
- [[column.CODE, column.NAME, column.TITLE] for column in group_nodes],
60
+ [[column.code, column.name, column.title] for column in group_nodes],
61
61
  )
62
62
 
63
63
 
@@ -35,7 +35,7 @@ metrics_typer = typer.Typer(
35
35
 
36
36
  @metrics_typer.command("list")
37
37
  def list_metrics(
38
- query: Annotated[str | None, typer.Argument(help="正则关键词")] = None,
38
+ query: Annotated[str | None, typer.Option("-q", "--query", help="正则关键词")] = None,
39
39
  ) -> None:
40
40
  """列出所有指标。
41
41
 
@@ -50,7 +50,7 @@ def list_metrics(
50
50
  >>> data-ops-cli metrics list
51
51
 
52
52
  通过正则过滤指标
53
- >>> data-ops-cli metrics list "网元.*"
53
+ >>> data-ops-cli metrics list -q "网元.*"
54
54
  """
55
55
  try:
56
56
  group_nodes = release_list_list(MetaType.METRICS)
@@ -62,7 +62,7 @@ def list_metrics(
62
62
  group_nodes = filter_nodes_by_pattern(group_nodes, query)
63
63
  print_list(
64
64
  ["code", "title", "subType"],
65
- [[column.CODE, column.TITLE, column.SUB_TYPE or "atomic"] for column in group_nodes],
65
+ [[column.code, column.title, column.subType or "atomic"] for column in group_nodes],
66
66
  )
67
67
 
68
68
 
@@ -28,7 +28,7 @@ report_typer = typer.Typer(name="report", help="Manage reports", no_args_is_help
28
28
 
29
29
  @report_typer.command("list", rich_help_panel="报告查询")
30
30
  def list_reports(
31
- query: Annotated[str | None, typer.Argument(help="正则关键词")] = None,
31
+ query: Annotated[str | None, typer.Option("-q", "--query", help="正则关键词")] = None,
32
32
  ) -> None:
33
33
  """列出所有报告。
34
34
 
@@ -42,7 +42,7 @@ def list_reports(
42
42
  >>> data-ops-cli report list
43
43
 
44
44
  通过正则关键词过滤报告
45
- >>> data-ops-cli report list "daily.*"
45
+ >>> data-ops-cli report list -q "daily.*"
46
46
  """
47
47
  try:
48
48
  group_nodes = release_list_list(MetaType.REPORT)
@@ -55,7 +55,7 @@ def list_reports(
55
55
 
56
56
  print_list(
57
57
  ["code", "title", "subType"],
58
- [[column.CODE, column.TITLE, column.SUB_TYPE or "doc"] for column in group_nodes],
58
+ [[column.code, column.title, column.subType or "doc"] for column in group_nodes],
59
59
  )
60
60
 
61
61
 
@@ -11,8 +11,10 @@ from pathlib import Path
11
11
  from typing import Annotated
12
12
 
13
13
  import typer
14
+ from dataops_cli.cli.utils import paginate_with_line_numbers, print_list
14
15
  from dataops_sdk.exceptions import DataOpsError
15
- from dataops_sdk.schemas.skill import MetaSkillSubType
16
+ from dataops_sdk.schemas.enums import MetaType
17
+ from dataops_sdk.schemas.skill import MetaSkillFileSubType, MetaSkillSubType
16
18
  from dataops_sdk.services import (
17
19
  SkillPackValidationError,
18
20
  service_delete_skill,
@@ -29,11 +31,10 @@ from dataops_sdk.services.skill import (
29
31
  service_skill_get_subfile_by_name,
30
32
  )
31
33
  from dataops_sdk.tiptap import TipTapTool
34
+ from dataops_sdk.tiptap.constants import TableStyle
32
35
  from pydantic_core import from_json
33
36
  from rich.console import Console
34
37
 
35
- from dataops_cli.cli.utils import paginate_with_line_numbers, print_list
36
-
37
38
  # ---------------------------------------------------------------------------
38
39
  # CLI 命令
39
40
  # ---------------------------------------------------------------------------
@@ -49,6 +50,7 @@ skill_file_typer = typer.Typer(
49
50
  no_args_is_help=True,
50
51
  )
51
52
  skill_typer.add_typer(skill_file_typer)
53
+ MAKRDOWN_TABLE_STYLE = TableStyle.MARKDOWN
52
54
 
53
55
 
54
56
  @skill_typer.command("list")
@@ -76,31 +78,44 @@ def list_cmd(
76
78
 
77
79
  print_list(
78
80
  ("name", "title", "subType", "remark"),
79
- [[it.NAME, it.TITLE, it.SUB_TYPE or "", it.REMARK or ""] for it in items],
81
+ [[it.name, it.title, it.subType or "", it.remark or ""] for it in items],
80
82
  )
81
83
 
82
84
 
83
85
  @skill_typer.command("detail", no_args_is_help=True)
84
86
  def detail_cmd(
85
- name: Annotated[str | None, typer.Argument(help="技能名称")],
87
+ name: Annotated[str, typer.Argument(help="技能名称")],
88
+ path: Annotated[str | None, typer.Argument(help="文件路径")] = None,
86
89
  start: Annotated[int | None, typer.Option("--start", help="起始位置", min=1)] = None,
87
90
  size: Annotated[int | None, typer.Option("--size", help="读取长度", min=1)] = None,
88
91
  ) -> None:
89
92
  """查看技能详情。
90
93
 
91
94
  Examples:
92
- >>> data-ops-cli skill detail --code my-skill
93
- >>> data-ops-cli skill detail --name my-skill --full
95
+ 获取 my-skill 技能文档
96
+ >>> data-ops-cli skill detail my-skill
97
+ 获取 my-skill 技能 scripts/main.py 文件详情
98
+ >>> data-ops-cli skill detail my-skill scripts/main.py
94
99
  """
95
100
  try:
96
- meta = service_get_skill_by_name(name)
101
+ meta = service_get_skill_by_name(name, path=path)
97
102
  except DataOpsError as e:
98
103
  typer.echo(f"错误: {e.message}")
99
104
  raise typer.Exit(code=1) from None
100
105
 
101
- content = TipTapTool().serialize(meta.data.editor)
106
+ add_line_num = False
107
+ if meta.type == MetaType.SKILL.value or (
108
+ meta.type == MetaType.SKILL_FILE.value and meta.subType == MetaSkillFileSubType.DOC.value
109
+ ):
110
+ content = TipTapTool(table_style=MAKRDOWN_TABLE_STYLE).serialize(meta.data.editor)
111
+ add_line_num = True
112
+ elif meta.type == MetaType.SKILL_FILE.value and meta.subType == MetaSkillFileSubType.CODE.value:
113
+ add_line_num = True
114
+ content = meta.data.content
102
115
 
103
- print(paginate_with_line_numbers(content, start=start, size=size))
116
+ if add_line_num:
117
+ content = paginate_with_line_numbers(content, start=start, size=size)
118
+ print(content)
104
119
 
105
120
 
106
121
  @skill_typer.command("upload", no_args_is_help=True)
@@ -248,7 +263,7 @@ def files_cmd(
248
263
  """列出某技能下的所有子文件。
249
264
 
250
265
  Examples:
251
- >>> data-ops-cli skill files --skill-id <id>
266
+ >>> data-ops-cli skill files my-skills
252
267
  """
253
268
  try:
254
269
  items = service_list_skill_files(name)
@@ -262,43 +277,6 @@ def files_cmd(
262
277
  print("\n".join(it.DIGEST for it in items))
263
278
 
264
279
 
265
- @skill_file_typer.command("detail")
266
- def files_detail_cmd(
267
- name: Annotated[str, typer.Argument(help="技能名称")],
268
- path: Annotated[str, typer.Argument(help="子文件路径")],
269
- start: Annotated[int | None, typer.Option("--start", help="起始位置", min=1)] = None,
270
- size: Annotated[int | None, typer.Option("--size", help="读取长度", min=1)] = None,
271
- ) -> None:
272
- """获取某技能下某子文件的详细信息。
273
-
274
- Examples:
275
- >>> data-ops-cli skill files detail <skill-name> scripts/main.py
276
- """
277
- try:
278
- meta = service_skill_get_subfile_by_name(name, path)
279
- except DataOpsError as e:
280
- typer.echo(f"错误: {e.message}")
281
- raise typer.Exit(code=1) from None
282
- content = None
283
- add_line_num = False
284
- if meta.subType == "doc":
285
- add_line_num = True
286
- content = TipTapTool().serialize(meta.data.get("editor", None))
287
- elif meta.subType == "image":
288
- raise NotImplementedError("不支持查看图片")
289
- elif meta.subType == "code":
290
- add_line_num = True
291
- content = meta.data.get("content", None)
292
- else:
293
- raise NotImplementedError(f"未知的子文件类型 {meta.subType}")
294
- if content is None:
295
- print("未查询到子文件内容")
296
-
297
- if add_line_num:
298
- content = paginate_with_line_numbers(content, start=start, size=size)
299
- print(content)
300
-
301
-
302
280
  @skill_file_typer.command("upload", no_args_is_help=True)
303
281
  def upload_sub_file_cmd(
304
282
  name: Annotated[str, typer.Argument(help="技能名称")],
@@ -43,7 +43,7 @@ config_typer.add_typer(column_typer)
43
43
  @table_typer.command("list")
44
44
  def list_table(
45
45
  datasource: Annotated[str, typer.Argument(help="数据源")],
46
- query: Annotated[str | None, typer.Argument(help="表名关键字")] = None,
46
+ query: Annotated[str | None, typer.Option("-q", "--query", help="表名关键字")] = None,
47
47
  ) -> None:
48
48
  """列出数据源中的表列表。
49
49
 
@@ -58,10 +58,10 @@ def list_table(
58
58
  >>> data-ops-cli table list mydatasource
59
59
 
60
60
  # 列出数据源中名称包含 "user" 的表
61
- >>> data-ops-cli table list mydatasource user
61
+ >>> data-ops-cli table list mydatasource -q user
62
62
 
63
63
  # 使用正则过滤表名
64
- >>> data-ops-cli table list mydatasource "^user_.*"
64
+ >>> data-ops-cli table list mydatasource -q "^user_.*"
65
65
  """
66
66
  try:
67
67
  group_nodes = service_list_tables(datasource)
@@ -77,7 +77,7 @@ def list_table(
77
77
  group_nodes = filter_nodes_by_pattern(group_nodes, query)
78
78
  print_list(
79
79
  ["code", "name", "alias", "remark"],
80
- [[column.CODE, column.NAME, column.TITLE, column.REMARK] for column in group_nodes],
80
+ [[column.code, column.name, column.title, column.remark] for column in group_nodes],
81
81
  )
82
82
 
83
83
 
@@ -111,6 +111,9 @@ def get_table_detail(
111
111
  # 显示完整的DDL信息(含关联字段)
112
112
  >>> data-ops-cli table detail mydatasource t_user --full
113
113
  """
114
+ if not name and not arg1.replace("_", "").replace("-", "").isnumeric():
115
+ print("输入参数错误 using `table detail <code>` or `table detail <datasource> <name>`")
116
+ raise typer.Exit(code=1) from None
114
117
  try:
115
118
  meta = (
116
119
  service_get_table_detail_by_name(arg1, name)
@@ -123,7 +126,11 @@ def get_table_detail(
123
126
 
124
127
  datasource = meta.subSystem
125
128
 
126
- print(datasource, meta.name)
129
+ assert meta.data, "元数据不存在"
130
+
131
+ print("datasource name code remark")
132
+ print(datasource, meta.name, meta.code, meta.remark or "")
133
+ print()
127
134
 
128
135
  def show_column(column: ColumnItem):
129
136
  if column.pk and column.labelKey:
@@ -205,6 +212,9 @@ def count_table_by_code(
205
212
  带查询条件统计数量
206
213
  >>> data-ops-cli table count mydatasource t_user --query '{"where":"status=1"}'
207
214
  """
215
+ if not name and not arg1.replace("_", "").replace("-", "").isnumeric():
216
+ print("输入参数错误 using `table detail <code>` or `table detail <datasource> <name>`")
217
+ raise typer.Exit(code=1) from None
208
218
  qp = SqlQueryParam.model_validate_json(query_param) if query_param else None
209
219
  try:
210
220
  count = (
@@ -228,14 +238,7 @@ def get_table_data(
228
238
  str | None, typer.Option("--query", "-q", help="查询参数(SqlQueryParam)")
229
239
  ] = None,
230
240
  ) -> None:
231
- """获取表的实际数据内容。
232
-
233
- 支持两种查询方式:
234
-
235
- 1. 通过表编码(CODE)直接查询
236
- 2. 通过数据源名称和表名组合查询
237
-
238
- 支持分页参数 ``-n/--page-num``、``-s/--page-size``,以及 ``--query/-q`` 条件过滤。
241
+ """获取表的实际数据内容。s
239
242
 
240
243
  Args:
241
244
  arg1: 表编码;当同时提供 ``name`` 时为数据源名称。
@@ -257,6 +260,10 @@ def get_table_data(
257
260
  # 带条件过滤查询
258
261
  >>> data-ops-cli table data mydatasource t_user --query '{"where":"status=1"}'
259
262
  """
263
+ if not name and not arg1.replace("_", "").replace("-", "").isnumeric():
264
+ print("输入参数错误 using `table detail <code>` or `table detail <datasource> <name>`")
265
+ raise typer.Exit(code=1) from None
266
+
260
267
  pp = PageParam(start=page_num * page_size, limit=page_size)
261
268
  qp = SqlQueryParam.model_validate_json(query_param) if query_param else SqlQueryParam()
262
269
  try:
@@ -319,13 +326,12 @@ def exec_sql(
319
326
  @column_typer.command("base", no_args_is_help=True)
320
327
  def set_column_config(
321
328
  datasource: Annotated[str, typer.Argument(help="编数据源")],
322
- name: Annotated[str | None, typer.Argument(help="表名")],
323
- column: Annotated[str, typer.Argument(help="列名")],
329
+ name: Annotated[str, typer.Argument(help="表名")],
330
+ column_name: Annotated[str, typer.Argument(help="列名")],
324
331
  title: Annotated[str | None, typer.Option(help="中文名称")] = None,
325
332
  pk: Annotated[bool | None, typer.Option(help="主键")] = None,
326
333
  nullable: Annotated[bool | None, typer.Option(help="是否可为空")] = None,
327
334
  labelKey: Annotated[bool | None, typer.Option(help="名称键")] = None,
328
- remark: Annotated[str | None, typer.Option(help="备注")] = None,
329
335
  ) -> None:
330
336
  """修改列基础配置。
331
337
 
@@ -337,10 +343,10 @@ def set_column_config(
337
343
  pk: 可选主键标记。
338
344
  nullable: 可空标记。
339
345
  labelKey: 可选名称键标记。
340
- remark: 可选备注。
341
346
  """
342
347
  meta = service_get_table_detail_by_name(datasource, name)
343
- column = next(filter(lambda c: c.name == column, meta.data.columns))
348
+ assert meta.data, f"表 {name} 元数据不存在"
349
+ column = next(filter(lambda c: c.name == column_name, meta.data.columns))
344
350
  if title:
345
351
  column.title = title
346
352
  if pk is not None:
@@ -349,18 +355,16 @@ def set_column_config(
349
355
  column.nullable = nullable
350
356
  if labelKey:
351
357
  column.labelKey = labelKey
352
- if remark:
353
- column.remark = remark
354
358
  result = release_list_update(meta)
355
359
  typer.echo(f"修改 {datasource} {name} {column.name} 完成")
356
360
 
357
361
 
358
362
  @column_typer.command("dict", no_args_is_help=True)
359
- def set_column_dict_config(
363
+ def get_column_dict_config(
360
364
  datasource: Annotated[str, typer.Argument(help="编数据源")],
361
- name: Annotated[str | None, typer.Argument(help="表名")],
362
- column: Annotated[str, typer.Argument(help="列名")],
363
- dict_name: Annotated[str, typer.Option("--dict", help="字典名称")] = None,
365
+ name: Annotated[str, typer.Argument(help="表名")],
366
+ column_name: Annotated[str, typer.Argument(help="列名")],
367
+ dict_name: Annotated[str, typer.Option("--dict", help="字典名称")],
364
368
  ) -> None:
365
369
  """设置列字典关系配置。
366
370
 
@@ -371,21 +375,23 @@ def set_column_dict_config(
371
375
  dict_name: 字典名称。
372
376
  """
373
377
  table_meta = service_get_table_detail_by_name(datasource, name)
374
- column_item = next(filter(lambda c: c.name == column, table_meta.data.columns))
378
+ assert table_meta.data, f"表 {name} 元数据不存在"
379
+ column_item = next(filter(lambda c: c.name == column_name, table_meta.data.columns), None)
380
+ assert column_item, f"列 {column_name} 不存在"
375
381
  dict_meta = service_get_dict_detail_by_name(datasource, dict_name)
376
382
  column_item.type = "dict"
377
383
  column_item.typeExt = DataBaseColumnDictExternal(
378
384
  ref__dict=DataBaseColumnReference(type="dict", code=dict_meta.code)
379
385
  )
380
386
  result = release_list_update(table_meta)
381
- typer.echo(f"修改 {datasource} {name} {column.name} 完成")
387
+ typer.echo(f"修改 {datasource} {name} {column_item.name} 完成")
382
388
 
383
389
 
384
390
  @column_typer.command("relation", no_args_is_help=True)
385
391
  def set_column_dict_config(
386
392
  datasource: Annotated[str, typer.Argument(help="编数据源")],
387
- name: Annotated[str | None, typer.Argument(help="表名")],
388
- column: Annotated[str, typer.Argument(help="列名")],
393
+ name: Annotated[str, typer.Argument(help="表名")],
394
+ column_name: Annotated[str, typer.Argument(help="列名")],
389
395
  r_name: Annotated[str, typer.Option(help="目标表名")] = None,
390
396
  r_col_name: Annotated[str, typer.Option(help="目标列名")] = None,
391
397
  ) -> None:
@@ -399,9 +405,13 @@ def set_column_dict_config(
399
405
  r_col_name: 目标列名。
400
406
  """
401
407
  table_meta = service_get_table_detail_by_name(datasource, name)
402
- column_item = next(filter(lambda c: c.name == column, table_meta.data.columns))
408
+ assert table_meta.data, f"表 {name} 元数据不存在"
409
+ column_item = next(filter(lambda c: c.name == column_name, table_meta.data.columns), None)
410
+ assert column_item, f"列 {column_name} 不存在"
403
411
  dst_table_meta = service_get_table_detail_by_name(datasource, r_name)
404
- dst_column_item = next(filter(lambda c: c.name == r_col_name, dst_table_meta.data.columns))
412
+ dst_column_item = next(filter(lambda c: c.name == r_col_name, dst_table_meta.data.columns), None)
413
+ assert dst_column_item, f"列 {r_col_name} 不存在"
414
+
405
415
  column_item.type = "relation"
406
416
  column_item.typeExt = DataBaseColumnTableExternal(
407
417
  ref__table=DataBaseColumnReference(type="table", code=dst_table_meta.code),
@@ -410,4 +420,4 @@ def set_column_dict_config(
410
420
  ),
411
421
  )
412
422
  result = release_list_update(table_meta)
413
- typer.echo(f"修改 {datasource} {name} {column.name} 完成")
423
+ typer.echo(f"修改 {datasource} {name} {column_item.name} 完成")
@@ -50,7 +50,7 @@ def list_widget(
50
50
 
51
51
  print_list(
52
52
  ["code", "title", "subType", "remark"],
53
- [[column.CODE, column.TITLE, column.SUB_TYPE, column.REMARK] for column in group_nodes],
53
+ [[column.code, column.title, column.subType, column.REMARK] for column in group_nodes],
54
54
  )
55
55
 
56
56
 
@@ -69,7 +69,7 @@ def list_workflow(
69
69
 
70
70
  print_list(
71
71
  ["code", "title", "subType", "remark"],
72
- [[column.CODE, column.TITLE, column.SUB_TYPE, column.REMARK] for column in group_nodes],
72
+ [[column.code, column.title, column.subType, column.remark] for column in group_nodes],
73
73
  )
74
74
 
75
75
 
File without changes