dimine-python-sdk 0.2.3__py3-none-any.whl → 0.2.4__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.
Files changed (143) hide show
  1. dimine_python_sdk/__init__.py +1 -1
  2. dimine_python_sdk/cli/commands/file.py +14 -19
  3. dimine_python_sdk/cli/commands/geometry.py +4 -4
  4. dimine_python_sdk/cli/utils/_utils.py +5 -5
  5. dimine_python_sdk/conn/base_conn_client.py +5 -1
  6. dimine_python_sdk/conn/conn_client.py +2 -2
  7. dimine_python_sdk/docs/guides/lib/io/SUMMARY.md +1 -0
  8. dimine_python_sdk/docs/guides/lib/io/dmo_file.md +159 -0
  9. dimine_python_sdk/docs/reference/SUMMARY.md +1 -0
  10. dimine_python_sdk/docs/reference/lib/io/dmo_file.md +3 -0
  11. dimine_python_sdk/lib/io/__init__.py +19 -0
  12. dimine_python_sdk/lib/io/dmo_file.py +327 -0
  13. dimine_python_sdk/lib/io/file_converter.py +3 -3
  14. dimine_python_sdk/lib/native/io.py +22 -10
  15. dimine_python_sdk/site/404.html +28 -0
  16. dimine_python_sdk/site/examples/cli_usage.html +28 -0
  17. dimine_python_sdk/site/examples/contour_modeling_visualization.html +28 -0
  18. dimine_python_sdk/site/examples/import_csv_to_drill_db.html +28 -0
  19. dimine_python_sdk/site/examples/lib_file_usage.html +28 -0
  20. dimine_python_sdk/site/examples/reserve_estimation_pipeline.html +28 -0
  21. dimine_python_sdk/site/examples/summary.html +28 -0
  22. dimine_python_sdk/site/guides/SUMMARY.html +28 -0
  23. dimine_python_sdk/site/guides/cli.html +28 -0
  24. dimine_python_sdk/site/guides/conn/SUMMARY.html +28 -0
  25. dimine_python_sdk/site/guides/conn/data_edit.html +28 -0
  26. dimine_python_sdk/site/guides/conn/data_get.html +28 -0
  27. dimine_python_sdk/site/guides/conn/features.html +28 -0
  28. dimine_python_sdk/site/guides/conn/io.html +28 -0
  29. dimine_python_sdk/site/guides/lib/SUMMARY.html +28 -0
  30. dimine_python_sdk/site/guides/lib/exploitation/SUMMARY.html +28 -0
  31. dimine_python_sdk/site/guides/lib/exploitation/contour_modeling.html +28 -0
  32. dimine_python_sdk/site/guides/lib/exploitation/implicit_modeling.html +28 -0
  33. dimine_python_sdk/site/guides/lib/exploitation/laneway.html +28 -0
  34. dimine_python_sdk/site/guides/lib/io/SUMMARY.html +29 -0
  35. dimine_python_sdk/site/guides/lib/io/dmb_file.html +28 -0
  36. dimine_python_sdk/site/guides/lib/io/dmd_file.html +28 -0
  37. dimine_python_sdk/site/guides/lib/io/dmf_file.html +28 -0
  38. dimine_python_sdk/site/guides/lib/io/dmg_file.html +29 -1
  39. dimine_python_sdk/site/guides/lib/io/dmo_file.html +2335 -0
  40. dimine_python_sdk/site/guides/lib/io/dmt_file.html +29 -1
  41. dimine_python_sdk/site/guides/lib/io/file_conversion.html +28 -0
  42. dimine_python_sdk/site/guides/lib/prospecting/SUMMARY.html +28 -0
  43. dimine_python_sdk/site/guides/lib/prospecting/drill_db.html +28 -0
  44. dimine_python_sdk/site/guides/lib/prospecting/reserve_estimation.html +28 -0
  45. dimine_python_sdk/site/guides/lib/visualization/SUMMARY.html +28 -0
  46. dimine_python_sdk/site/guides/lib/visualization/visualization.html +28 -0
  47. dimine_python_sdk/site/guides/models/SUMMARY.html +28 -0
  48. dimine_python_sdk/site/guides/models/data_types.html +28 -0
  49. dimine_python_sdk/site/index.html +28 -0
  50. dimine_python_sdk/site/objects.inv +0 -0
  51. dimine_python_sdk/site/quickstart.html +28 -0
  52. dimine_python_sdk/site/reference/SUMMARY.html +29 -0
  53. dimine_python_sdk/site/reference/cli/commands/camera.html +28 -0
  54. dimine_python_sdk/site/reference/cli/commands/convert.html +28 -0
  55. dimine_python_sdk/site/reference/cli/commands/datatable.html +28 -0
  56. dimine_python_sdk/site/reference/cli/commands/entity.html +28 -0
  57. dimine_python_sdk/site/reference/cli/commands/feature.html +28 -0
  58. dimine_python_sdk/site/reference/cli/commands/file.html +89 -63
  59. dimine_python_sdk/site/reference/cli/commands/geometry.html +35 -7
  60. dimine_python_sdk/site/reference/cli/commands/laneway.html +28 -0
  61. dimine_python_sdk/site/reference/cli/commands/layer.html +28 -0
  62. dimine_python_sdk/site/reference/cli/commands/text.html +28 -0
  63. dimine_python_sdk/site/reference/conn/base_conn_client.html +50 -14
  64. dimine_python_sdk/site/reference/conn/conn_client.html +28 -0
  65. dimine_python_sdk/site/reference/lib/bridge.html +132 -82
  66. dimine_python_sdk/site/reference/lib/exploitation/api.html +28 -0
  67. dimine_python_sdk/site/reference/lib/exploitation/contour_modeling.html +28 -0
  68. dimine_python_sdk/site/reference/lib/exploitation/implicit_modeling.html +28 -0
  69. dimine_python_sdk/site/reference/lib/exploitation/lane_way.html +28 -0
  70. dimine_python_sdk/site/reference/lib/exploitation/models.html +28 -0
  71. dimine_python_sdk/site/reference/lib/io/dmb_file.html +28 -0
  72. dimine_python_sdk/site/reference/lib/io/dmd_file.html +28 -0
  73. dimine_python_sdk/site/reference/lib/io/dmf_file.html +28 -0
  74. dimine_python_sdk/site/reference/lib/io/dmg_file.html +28 -0
  75. dimine_python_sdk/site/reference/lib/io/dmo_file.html +3003 -0
  76. dimine_python_sdk/site/reference/lib/io/dmt_file.html +28 -0
  77. dimine_python_sdk/site/reference/lib/io/file_converter.html +32 -4
  78. dimine_python_sdk/site/reference/lib/io/models.html +28 -0
  79. dimine_python_sdk/site/reference/lib/native/algorithm.html +28 -0
  80. dimine_python_sdk/site/reference/lib/native/data_table.html +28 -0
  81. dimine_python_sdk/site/reference/lib/native/exploitation.html +28 -0
  82. dimine_python_sdk/site/reference/lib/native/geometry.html +28 -0
  83. dimine_python_sdk/site/reference/lib/native/io.html +132 -82
  84. dimine_python_sdk/site/reference/lib/native/models.html +28 -0
  85. dimine_python_sdk/site/reference/lib/native/prospecting.html +28 -0
  86. dimine_python_sdk/site/reference/lib/prospecting/api.html +28 -0
  87. dimine_python_sdk/site/reference/lib/prospecting/block_model.html +28 -0
  88. dimine_python_sdk/site/reference/lib/prospecting/compositing.html +28 -0
  89. dimine_python_sdk/site/reference/lib/prospecting/drill_db.html +28 -0
  90. dimine_python_sdk/site/reference/lib/prospecting/ellipsoid.html +28 -0
  91. dimine_python_sdk/site/reference/lib/prospecting/high_grade.html +28 -0
  92. dimine_python_sdk/site/reference/lib/prospecting/models.html +28 -0
  93. dimine_python_sdk/site/reference/lib/visualization/exceptions.html +28 -0
  94. dimine_python_sdk/site/reference/lib/visualization/models.html +28 -0
  95. dimine_python_sdk/site/reference/lib/visualization/tin_renderer.html +28 -0
  96. dimine_python_sdk/site/reference/logger.html +28 -0
  97. dimine_python_sdk/site/reference/models/conn.html +28 -0
  98. dimine_python_sdk/site/reference/models/errors.html +28 -0
  99. dimine_python_sdk/site/reference/models/types.html +28 -0
  100. dimine_python_sdk/site/search/search_index.json +1 -1
  101. dimine_python_sdk/site/sitemap.xml +90 -82
  102. dimine_python_sdk/site/sitemap.xml.gz +0 -0
  103. dimine_python_sdk/site/summary.html +28 -0
  104. {dimine_python_sdk-0.2.3.dist-info → dimine_python_sdk-0.2.4.dist-info}/METADATA +1 -1
  105. {dimine_python_sdk-0.2.3.dist-info → dimine_python_sdk-0.2.4.dist-info}/RECORD +108 -138
  106. {dimine_python_sdk-0.2.3.dist-info → dimine_python_sdk-0.2.4.dist-info}/top_level.txt +0 -2
  107. outline/build_dmd_from_scratch.py +0 -426
  108. outline/contour_extract.py +0 -450
  109. outline/contour_match.py +0 -1095
  110. outline/contour_pipeline.py +0 -586
  111. outline/contour_validate.py +0 -645
  112. outline/dmd_to_dmg.py +0 -164
  113. outline/drill_to_reserves.py +0 -825
  114. outline/ellipsoid_params.py +0 -106
  115. outline/implicit_modeling.py +0 -365
  116. outline/read_dmb.py +0 -200
  117. outline/read_dwg.py +0 -353
  118. outline/test_dmd_file.py +0 -322
  119. outline/test_dmg_to_segments.py +0 -317
  120. outline/test_extend_table.py +0 -193
  121. tests/conn_example.py +0 -70
  122. tests/conn_test.py +0 -269
  123. tests/test_conn_client_unit.py +0 -449
  124. tests/test_create_geometry_file_transfer.py +0 -289
  125. tests/test_csv_import_flow.py +0 -169
  126. tests/test_dmg_file.py +0 -467
  127. tests/test_dmt_file.py +0 -178
  128. tests/test_file_conversion.py +0 -544
  129. tests/test_high_grade_samples.py +0 -228
  130. tests/test_implicit_modeling.py +0 -284
  131. tests/test_laneway.py +0 -341
  132. tests/test_layer_isolation.py +0 -219
  133. tests/test_lib_file.py +0 -731
  134. tests/test_lib_refactor.py +0 -304
  135. tests/test_modeling.py +0 -338
  136. tests/test_native_unit.py +0 -353
  137. tests/test_prospecting_api.py +0 -1287
  138. tests/test_sample_compositing.py +0 -398
  139. tests/test_tin_renderer.py +0 -454
  140. tests/ws_client.py +0 -60
  141. tests/ws_server.py +0 -271
  142. {dimine_python_sdk-0.2.3.dist-info → dimine_python_sdk-0.2.4.dist-info}/WHEEL +0 -0
  143. {dimine_python_sdk-0.2.3.dist-info → dimine_python_sdk-0.2.4.dist-info}/entry_points.txt +0 -0
@@ -4,7 +4,7 @@ from pathlib import Path
4
4
  from typing import Any
5
5
 
6
6
  DOCS_PATH = Path(__file__).parent / "docs"
7
- __VERSION__ = "0.2.3" # 由 build.bat 中的 generate_version.py 自动更新
7
+ __VERSION__ = "0.2.4" # 由 build.bat 中的 generate_version.py 自动更新
8
8
 
9
9
 
10
10
  _LAZY_IMPORTS: dict[str, Any] = {}
@@ -1,12 +1,8 @@
1
1
  """文件相关 CLI 命令。"""
2
2
 
3
- import os
4
-
5
3
  from dimine_python_sdk.cli.utils._utils import (
6
- close_client,
7
4
  get_client,
8
5
  handle_sdk_error,
9
- open_client,
10
6
  output_error,
11
7
  output_result,
12
8
  raise_or_exit,
@@ -54,21 +50,20 @@ def cmd_file_save(fmt: str, output_path: str, file_id: str | None) -> None:
54
50
 
55
51
  async def _run():
56
52
  nonlocal file_id
53
+ client = await get_client()
57
54
  if not file_id:
58
- async with open_client() as client:
59
- files = await client.get_files()
60
- if not files:
61
- raise_or_exit("没有打开的文件。请先在 Dimine 中打开文件,或提供 --file-id 参数。", fmt)
62
- if len(files) == 1:
63
- file_id = files[0].id
64
- else:
65
- file_list = "\n".join([f" - id: {f.id}, name: {f.name}" for f in files])
66
- raise_or_exit(
67
- f"当前打开了 {len(files)} 个文件,请指定 --file-id:\n{file_list}",
68
- fmt,
69
- )
70
- async with open_client() as client:
71
- await client.export_file(file_id=file_id, file_path=save_path)
55
+ files = await client.get_files()
56
+ if not files:
57
+ raise_or_exit("没有打开的文件。请先在 Dimine 中打开文件,或提供 --file-id 参数。", fmt)
58
+ if len(files) == 1:
59
+ file_id = files[0].id
60
+ else:
61
+ file_list = "\n".join([f" - id: {f.id}, name: {f.name}" for f in files])
62
+ raise_or_exit(
63
+ f"当前打开了 {len(files)} 个文件,请指定 --file-id:\n{file_list}",
64
+ fmt,
65
+ )
66
+ await client.export_file(file_id=file_id, file_path=save_path)
72
67
  return {
73
68
  "success": True,
74
69
  "file_id": file_id,
@@ -77,7 +72,7 @@ def cmd_file_save(fmt: str, output_path: str, file_id: str | None) -> None:
77
72
  }
78
73
 
79
74
  try:
80
- result = asyncio.run(_run())
75
+ result = run_cli_async(_run())
81
76
  output_result(result, fmt)
82
77
  except SystemExit:
83
78
  raise
@@ -308,9 +308,9 @@ def _build_partial_geometry_objects(geometries: list) -> list:
308
308
  return result
309
309
 
310
310
 
311
- def cmd_geometry_get(fmt: str, file_id: str, layer_id: str | None,
312
- entity_types: str | None = None, features: str | None = None,
313
- with_geometry: bool = False) -> None:
311
+ def cmd_geometry_list(fmt: str, file_id: str, layer_id: str | None,
312
+ entity_types: str | None = None, features: str | None = None,
313
+ with_geometry: bool = False) -> None:
314
314
  """获取图层中的几何体对象(需 Dimine 运行)。
315
315
 
316
316
  默认只返回几何体的基础信息(id、file、layer、feature、type、color、properties)。
@@ -610,7 +610,7 @@ def register_commands(subparsers, format_parent) -> None:
610
610
 
611
611
 
612
612
  COMMAND_HANDLERS = {
613
- "geometry-list": lambda args: cmd_geometry_get(args.format, args.file_id, args.layer_id,
613
+ "geometry-list": lambda args: cmd_geometry_list(args.format, args.file_id, args.layer_id,
614
614
  args.entity_types, args.features,
615
615
  args.with_geometry),
616
616
  "geometry-create": lambda args: cmd_geometry_create(args.format, args.geometries,
@@ -26,17 +26,17 @@ if TYPE_CHECKING:
26
26
  _SDK_AVAILABLE: bool | None = None # None = 尚未检查
27
27
  _local_sdk_available: bool | None = None # None = 尚未检查
28
28
  _import_error: str = ""
29
- open_client = None # type: ignore[assignment]
29
+ _open_client: Any = None # 惰性缓存的 open_client 函数(私有,勿直接 import)
30
30
 
31
31
 
32
32
  def _check_remote_sdk() -> bool:
33
33
  """惰性检查远程 SDK 是否可用。首次调用时导入 conn 模块链并缓存结果。"""
34
- global _SDK_AVAILABLE, _import_error, open_client
34
+ global _SDK_AVAILABLE, _import_error, _open_client
35
35
  if _SDK_AVAILABLE is not None:
36
36
  return _SDK_AVAILABLE
37
37
  try:
38
- from dimine_python_sdk.conn.conn_client import open_client as _open_client # type: ignore[no-redef]
39
- open_client = _open_client
38
+ from dimine_python_sdk.conn.conn_client import open_client as _conn_open_client
39
+ _open_client = _conn_open_client
40
40
  _SDK_AVAILABLE = True
41
41
  except ImportError as e:
42
42
  _import_error = str(e)
@@ -157,7 +157,7 @@ async def get_client()->ConnClient:
157
157
  _client_loop_id = None
158
158
 
159
159
  if _client_instance is None:
160
- _client_ctx = open_client()
160
+ _client_ctx = _open_client()
161
161
  _client_instance = await _client_ctx.__aenter__()
162
162
  _client_loop_id = id(asyncio.get_running_loop())
163
163
  return _client_instance
@@ -19,6 +19,7 @@ class BaseConnClient:
19
19
  model_config = {"arbitrary_types_allowed": True}
20
20
 
21
21
  url: Optional[str] = "ws://127.0.0.1:8000"
22
+ max_size: Optional[int] = None
22
23
  is_connected: Optional[bool] = False
23
24
  pending_requests: Dict[str, Tuple[asyncio.Future, Callable]] = field(default_factory=dict)
24
25
  event_handlers: Dict[str, List[Callable]] = field(default_factory=dict)
@@ -106,7 +107,10 @@ class BaseConnClient:
106
107
 
107
108
  async def connect(self)-> bool:
108
109
  try:
109
- self.websocket = await websockets.connect(self.url, close_timeout=1)
110
+ connect_kwargs: Dict[str, Any] = {"close_timeout": 1}
111
+ if self.max_size is not None:
112
+ connect_kwargs["max_size"] = self.max_size
113
+ self.websocket = await websockets.connect(self.url, **connect_kwargs)
110
114
  self.is_connected = True
111
115
  logger.info("success connected to %s", self.url)
112
116
  if self.receive_task is None or self.receive_task.done():
@@ -744,8 +744,8 @@ class ConnClient(BaseConnClient):
744
744
 
745
745
 
746
746
  @asynccontextmanager
747
- async def open_client(url:Optional[str]=None)->AsyncGenerator[ConnClient,None]:
748
- client = ConnClient(url=url or "ws://127.0.0.1:8000")
747
+ async def open_client(url:Optional[str]=None, max_size:Optional[int]=None)->AsyncGenerator[ConnClient,None]:
748
+ client = ConnClient(url=url or "ws://127.0.0.1:8000", max_size=max_size)
749
749
  await client.connect()
750
750
  yield client
751
751
  await client.close()
@@ -6,5 +6,6 @@
6
6
  * [DMG 钻孔可视化](dmg_file.md)
7
7
  * [DMT 数据表文件](dmt_file.md)
8
8
  * [DMB 块段模型](dmb_file.md)
9
+ * [DMO 炮孔数据库](dmo_file.md)
9
10
 
10
11
  > 完整的钻孔数据库使用流程(CSV 导入、列名映射、组合样等)见 **[地质勘探 / 钻孔数据库](../prospecting/drill_db.md)**。
@@ -0,0 +1,159 @@
1
+ # DMO 炮孔数据库文件
2
+
3
+ `dimine_python_sdk.lib.io` 提供 `DmoFile` 类用于读写 Dimine 炮孔数据库文件(`.dmo`)。DMO 本质上是带固定表头(炮孔数据库标准字段,新版 26 列)的 DMT 数据表文件,API 将其映射为 `pandas.DataFrame`,加载时对表头做**宽松校验**(缺列/多列/类型不符只记录告警、不抛异常),保存时按固定表头还原字段类型,避免 pandas dtype 推断丢失 `long`/`binary` 等类型。
4
+
5
+ ---
6
+
7
+ ## 一、加载与保存
8
+
9
+ ### 从文件加载
10
+
11
+ ```python
12
+ from dimine_python_sdk.lib.io import DmoFile
13
+
14
+ dmo = DmoFile("炮孔数据库-data.dmo")
15
+ print(dmo.columns) # 26 列标准字段
16
+ print(dmo.record_count) # 炮孔数量
17
+ print(dmo.data.head())
18
+ print(dmo.header_warnings) # 表头非标准告警(如有)
19
+ ```
20
+
21
+ ### 保存到文件
22
+
23
+ ```python
24
+ dmo.data.loc[0, "孔径"] = 250.0
25
+ dmo.save("output.dmo") # 另存为新文件(无扩展名时自动追加 .dmo)
26
+ dmo.save() # 覆盖原文件
27
+ ```
28
+
29
+ ### 从 DataFrame 创建并保存
30
+
31
+ ```python
32
+ import pandas as pd
33
+ from dimine_python_sdk.lib.io import DmoFile
34
+
35
+ df = pd.DataFrame({
36
+ "爆破区域": ["M01", "M01"],
37
+ "炮孔编号": ["BH-01", "BH-02"],
38
+ "孔径": [220.0, 220.0],
39
+ "孔深": [12.0, 13.5],
40
+ })
41
+ DmoFile(data=df).save("new.dmo")
42
+ ```
43
+
44
+ ### 上下文管理器
45
+
46
+ ```python
47
+ from dimine_python_sdk.lib.io import dmo_conn
48
+
49
+ with dmo_conn("炮孔数据库.dmo") as dmo:
50
+ print(dmo.info)
51
+ dmo.data["孔径"] = dmo.data["孔径"] * 1.1
52
+ dmo.save()
53
+ ```
54
+
55
+ ---
56
+
57
+ ## 二、固定表头 schema
58
+
59
+ DMO 文件拥有固定的 26 列标准字段,定义于模块常量 `DMO_FIELD_SCHEMA`:
60
+
61
+ ```python
62
+ from dimine_python_sdk.lib.io import DMO_FIELD_NAMES, DMO_FIELD_TYPES
63
+
64
+ print(DMO_FIELD_NAMES) # 字段名列表(26 项)
65
+ print(DMO_FIELD_TYPES) # {'爆破区域': 'string', '炮孔Handle': 'long', ...}
66
+
67
+ dmo.schema # [{"name": "爆破区域", "type": "string"}, ...]
68
+ ```
69
+
70
+ 字段类型支持 `string` / `long` / `int` / `double` / `binary`。标准字段覆盖:
71
+
72
+ - 标识:`爆破区域`、`炮孔编号`、`虚拟炮孔`、`起爆点炮孔`、`炮孔Handle`
73
+ - 起爆参数:`起爆延时`、`所属爆堆`、`地表起爆时间`、`孔内起爆时间`、`孔内分段起爆`
74
+ - 孔口/孔底坐标:`孔口坐标X/Y/Z`、`孔底坐标X/Y/Z`
75
+ - 孔参数:`孔径`、`孔深`、`方位角`、`倾角`
76
+ - 装药参数:`装药半径相对孔径的收缩比例`、`装药重量`、`装药长度`、`单耗面积`、`装药结构`、`连线信息`
77
+
78
+ ---
79
+
80
+ ## 三、表头宽松校验
81
+
82
+ 加载时 `DmoFile` 会对表头做宽松校验,非标准列或缺列**不会**抛异常,而是记录到 `header_warnings`:
83
+
84
+ ```python
85
+ dmo = DmoFile("旧版炮孔数据.dmo")
86
+
87
+ for w in dmo.header_warnings:
88
+ print(w)
89
+ # 缺少标准列: ['孔内分段起爆', '连线信息']
90
+ # 含非标准列: ['孔内延时']
91
+ # 字段 '炮孔Handle' 类型不符: 期望 long, 实际 double
92
+ ```
93
+
94
+ 校验规则:
95
+ - **缺标准列**:记录告警,缺失列在 DataFrame 中不存在
96
+ - **含非标准列**:记录告警,非标准列在保存时按 pandas dtype 回退推断类型
97
+ - **类型不符**:记录告警,保存时仍按 schema 中的标准类型还原
98
+
99
+ `dmo.info` 在继承 `DmtFile` 摘要信息的基础上,额外附带 `header_warnings`。
100
+
101
+ ---
102
+
103
+ ## 四、数据访问
104
+
105
+ `DmoFile` 继承 `DmtFile`,拥有完整的数据表操作接口:
106
+
107
+ ```python
108
+ dmo.name # "炮孔数据库" — 文件名(不含扩展名)
109
+ dmo.columns # 字段名列表
110
+ dmo.shape # (行数, 列数)
111
+ dmo.record_count # 炮孔行数
112
+ dmo.empty # 是否为空
113
+
114
+ # DataFrame 访问
115
+ df = dmo.data # 内部 DataFrame 引用(修改会影响 dmo)
116
+ df = dmo.to_dataframe() # 独立副本
117
+
118
+ # 行操作
119
+ row = dmo.get_record(0) # 单行字典
120
+ dmo.set_value(0, "孔径", 250.0) # 设置单元格
121
+ dmo.add_record({"炮孔编号": "BH-03"}) # 追加一行,返回新索引
122
+
123
+ # 列访问
124
+ dmo["孔径"] # 整列列表
125
+ "孔径" in dmo # True
126
+ ```
127
+
128
+ 更完整的数据访问说明见 [DMT 数据表文件](dmt_file.md)。
129
+
130
+ ---
131
+
132
+ ## 五、异常处理
133
+
134
+ ```python
135
+ from dimine_python_sdk.lib.io import DmoError, DmoLoadError, DmoSaveError
136
+
137
+ try:
138
+ dmo = DmoFile("not_exist.dmo")
139
+ except DmoLoadError as e:
140
+ print(f"加载失败: {e}")
141
+
142
+ try:
143
+ dmo = DmoFile()
144
+ dmo.save() # 未指定路径
145
+ except DmoSaveError as e:
146
+ print(f"保存失败: {e}")
147
+ ```
148
+
149
+ 异常层次:
150
+ - `DmoError(RuntimeError)` — 基类
151
+ - `DmoLoadError(DmoError)` — 加载失败
152
+ - `DmoSaveError(DmoError)` — 保存失败
153
+
154
+ ---
155
+
156
+ ## 参考链接
157
+
158
+ - [DMT 数据表文件](dmt_file.md) — 基础数据表访问接口
159
+ - [API 参考:dmo_file](../../../reference/lib/io/dmo_file.md)
@@ -23,6 +23,7 @@
23
23
  * [dmd_file](lib/io/dmd_file.md)
24
24
  * [dmg_file](lib/io/dmg_file.md)
25
25
  * [dmt_file](lib/io/dmt_file.md)
26
+ * [dmo_file](lib/io/dmo_file.md)
26
27
  * [file_converter](lib/io/file_converter.md)
27
28
  * [models](lib/io/models.md)
28
29
  * [algorithm](lib/native/algorithm.md)
@@ -0,0 +1,3 @@
1
+ # dmo_file
2
+
3
+ ::: dimine_python_sdk.lib.io.dmo_file
@@ -25,6 +25,16 @@ from dimine_python_sdk.lib.io.dmg_file import (
25
25
  DmgValidationError,
26
26
  dmg_conn,
27
27
  )
28
+ from dimine_python_sdk.lib.io.dmo_file import (
29
+ DMO_FIELD_NAMES,
30
+ DMO_FIELD_SCHEMA,
31
+ DMO_FIELD_TYPES,
32
+ DmoError,
33
+ DmoFile,
34
+ DmoLoadError,
35
+ DmoSaveError,
36
+ dmo_conn,
37
+ )
28
38
  from dimine_python_sdk.lib.io.dmt_file import (
29
39
  DmtError,
30
40
  DmtFile,
@@ -91,4 +101,13 @@ __all__ = [
91
101
  "DmtError",
92
102
  "DmtLoadError",
93
103
  "DmtSaveError",
104
+ # DMO 文件操作
105
+ "DmoFile",
106
+ "dmo_conn",
107
+ "DmoError",
108
+ "DmoLoadError",
109
+ "DmoSaveError",
110
+ "DMO_FIELD_SCHEMA",
111
+ "DMO_FIELD_NAMES",
112
+ "DMO_FIELD_TYPES",
94
113
  ]