chemchat 0.1.0__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.
@@ -0,0 +1,116 @@
1
+ Metadata-Version: 2.4
2
+ Name: chemchat
3
+ Version: 0.1.0
4
+ Summary: 化学分子智能对话与可视化系统 — 面向中小学生的化学学习助手
5
+ Author: chemchat contributors
6
+ License: MIT
7
+ Keywords: chemistry,molecule,visualization,education,chat,3D
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Intended Audience :: Education
10
+ Classifier: Topic :: Education
11
+ Classifier: Topic :: Scientific/Engineering :: Chemistry
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: License :: OSI Approved :: MIT License
17
+ Classifier: Environment :: X11 Applications :: Qt
18
+ Requires-Python: >=3.10
19
+ Description-Content-Type: text/markdown
20
+ Requires-Dist: PySide6>=6.5
21
+ Requires-Dist: numpy
22
+ Requires-Dist: requests
23
+ Requires-Dist: matplotlib
24
+ Requires-Dist: pyqtgraph>=0.13
25
+ Requires-Dist: PyOpenGL
26
+ Provides-Extra: rdkit
27
+ Requires-Dist: rdkit-pypi; extra == "rdkit"
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest; extra == "dev"
30
+ Requires-Dist: build; extra == "dev"
31
+ Requires-Dist: twine; extra == "dev"
32
+
33
+ # ChemChat — 化学分子智能对话与可视化系统
34
+
35
+ 面向中小学生的化学学习助手,支持分子2D/3D可视化、LLM智能对话、化学实体自动识别。
36
+
37
+ ## 安装
38
+
39
+ ```bash
40
+ pip install chemchat
41
+ ```
42
+
43
+ ### 可选依赖
44
+
45
+ ```bash
46
+ # RDKit 分子处理(推荐,支持更精确的2D/3D结构生成)
47
+ conda install rdkit
48
+ # 或
49
+ pip install rdkit-pypi
50
+
51
+ # PySide6 WebEngine(3D分子查看器需要)
52
+ pip install PySide6-WebEngine
53
+ ```
54
+
55
+ ## 使用
56
+
57
+ ### 启动 GUI
58
+
59
+ ```bash
60
+ chemchat
61
+ ```
62
+
63
+ 或在 Python 中:
64
+
65
+ ```python
66
+ from chemchat.__main__ import main
67
+ main()
68
+ ```
69
+
70
+ ### Python API
71
+
72
+ ```python
73
+ from chemchat.engine.mol_parser import MoleculeParser
74
+ from chemchat.engine.entity_extractor import EntityExtractor
75
+ from chemchat.engine.element_data import ELEMENTS, format_element_info, get_element
76
+ from chemchat.db.knowledge_base import init_db, search_molecules
77
+
78
+ # 初始化知识库
79
+ init_db()
80
+
81
+ # 分子解析
82
+ parser = MoleculeParser()
83
+ result = parser.parse("H2O")
84
+ print(result["formula"]) # H2O
85
+ print(result["elements"]) # ['O', 'H', 'H']
86
+
87
+ # 实体提取
88
+ ext = EntityExtractor()
89
+ entities = ext.extract("苯和乙醇是常见溶剂")
90
+ # [(苯, c1ccccc1, 0, 1), (乙醇, CCO, 2, 4)]
91
+
92
+ # 元素信息
93
+ info = format_element_info("Fe")
94
+ # <b>铁 (Fe)</b> <i>Iron</i><br>原子序数: 26...
95
+ ```
96
+
97
+ ## 功能特性
98
+
99
+ - **分子可视化**:2D/3D切换,支持球棒模型、空间填充等多种显示风格
100
+ - **智能对话**:集成 Ollama LLM,自动识别对话中的化学物质并可视化
101
+ - **实体提取**:自动识别中文化学名、化学式、SMILES等
102
+ - **知识库**:内置57+种常见化学物质的详细数据
103
+ - **元素信息**:46种常见元素的完整周期表数据,点击原子即时查看
104
+ - **数据库管理**:支持CRUD、JSON/CSV导入导出
105
+
106
+ ## 技术栈
107
+
108
+ - PySide6 + WebEngine (3D分子渲染)
109
+ - RDKit (分子结构解析)
110
+ - 3Dmol.js (3D可视化)
111
+ - Ollama (LLM对话)
112
+ - SQLite (知识库)
113
+
114
+ ## License
115
+
116
+ MIT
@@ -0,0 +1,84 @@
1
+ # ChemChat — 化学分子智能对话与可视化系统
2
+
3
+ 面向中小学生的化学学习助手,支持分子2D/3D可视化、LLM智能对话、化学实体自动识别。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ pip install chemchat
9
+ ```
10
+
11
+ ### 可选依赖
12
+
13
+ ```bash
14
+ # RDKit 分子处理(推荐,支持更精确的2D/3D结构生成)
15
+ conda install rdkit
16
+ # 或
17
+ pip install rdkit-pypi
18
+
19
+ # PySide6 WebEngine(3D分子查看器需要)
20
+ pip install PySide6-WebEngine
21
+ ```
22
+
23
+ ## 使用
24
+
25
+ ### 启动 GUI
26
+
27
+ ```bash
28
+ chemchat
29
+ ```
30
+
31
+ 或在 Python 中:
32
+
33
+ ```python
34
+ from chemchat.__main__ import main
35
+ main()
36
+ ```
37
+
38
+ ### Python API
39
+
40
+ ```python
41
+ from chemchat.engine.mol_parser import MoleculeParser
42
+ from chemchat.engine.entity_extractor import EntityExtractor
43
+ from chemchat.engine.element_data import ELEMENTS, format_element_info, get_element
44
+ from chemchat.db.knowledge_base import init_db, search_molecules
45
+
46
+ # 初始化知识库
47
+ init_db()
48
+
49
+ # 分子解析
50
+ parser = MoleculeParser()
51
+ result = parser.parse("H2O")
52
+ print(result["formula"]) # H2O
53
+ print(result["elements"]) # ['O', 'H', 'H']
54
+
55
+ # 实体提取
56
+ ext = EntityExtractor()
57
+ entities = ext.extract("苯和乙醇是常见溶剂")
58
+ # [(苯, c1ccccc1, 0, 1), (乙醇, CCO, 2, 4)]
59
+
60
+ # 元素信息
61
+ info = format_element_info("Fe")
62
+ # <b>铁 (Fe)</b> <i>Iron</i><br>原子序数: 26...
63
+ ```
64
+
65
+ ## 功能特性
66
+
67
+ - **分子可视化**:2D/3D切换,支持球棒模型、空间填充等多种显示风格
68
+ - **智能对话**:集成 Ollama LLM,自动识别对话中的化学物质并可视化
69
+ - **实体提取**:自动识别中文化学名、化学式、SMILES等
70
+ - **知识库**:内置57+种常见化学物质的详细数据
71
+ - **元素信息**:46种常见元素的完整周期表数据,点击原子即时查看
72
+ - **数据库管理**:支持CRUD、JSON/CSV导入导出
73
+
74
+ ## 技术栈
75
+
76
+ - PySide6 + WebEngine (3D分子渲染)
77
+ - RDKit (分子结构解析)
78
+ - 3Dmol.js (3D可视化)
79
+ - Ollama (LLM对话)
80
+ - SQLite (知识库)
81
+
82
+ ## License
83
+
84
+ MIT
@@ -0,0 +1,51 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "chemchat"
7
+ version = "0.1.0"
8
+ description = "化学分子智能对话与可视化系统 — 面向中小学生的化学学习助手"
9
+ readme = "README.md"
10
+ license = {text = "MIT"}
11
+ requires-python = ">=3.10"
12
+ authors = [
13
+ {name = "chemchat contributors"},
14
+ ]
15
+ keywords = ["chemistry", "molecule", "visualization", "education", "chat", "3D"]
16
+ classifiers = [
17
+ "Development Status :: 3 - Alpha",
18
+ "Intended Audience :: Education",
19
+ "Topic :: Education",
20
+ "Topic :: Scientific/Engineering :: Chemistry",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.10",
23
+ "Programming Language :: Python :: 3.11",
24
+ "Programming Language :: Python :: 3.12",
25
+ "License :: OSI Approved :: MIT License",
26
+ "Environment :: X11 Applications :: Qt",
27
+ ]
28
+ dependencies = [
29
+ "PySide6>=6.5",
30
+ "numpy",
31
+ "requests",
32
+ "matplotlib",
33
+ "pyqtgraph>=0.13",
34
+ "PyOpenGL",
35
+ ]
36
+
37
+ [project.optional-dependencies]
38
+ rdkit = ["rdkit-pypi"]
39
+ dev = ["pytest", "build", "twine"]
40
+
41
+ [project.scripts]
42
+ chemchat = "chemchat.__main__:main"
43
+
44
+ [tool.setuptools.packages.find]
45
+ where = ["src"]
46
+
47
+ [tool.setuptools.package-data]
48
+ chemchat = ["db/*.db"]
49
+
50
+ [tool.setuptools]
51
+ include-package-data = true
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ """chemchat — 化学分子智能对话与可视化系统"""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,20 @@
1
+ """chemchat — 启动入口"""
2
+ import sys
3
+ import os
4
+
5
+
6
+ def main():
7
+ os.environ.setdefault('QT_QPA_PLATFORM', '')
8
+ from PySide6.QtWidgets import QApplication
9
+ from chemchat.db.knowledge_base import init_db
10
+ from chemchat.ui.main_window import MainWindow
11
+
12
+ init_db()
13
+ app = QApplication(sys.argv)
14
+ win = MainWindow()
15
+ win.show()
16
+ sys.exit(app.exec())
17
+
18
+
19
+ if __name__ == "__main__":
20
+ main()
@@ -0,0 +1 @@
1
+ # package
@@ -0,0 +1,281 @@
1
+ """SQLite 知识库 — 120+ 权威化学物质 + SMILES + CRUD + 导出"""
2
+ import sqlite3, os, json, csv
3
+ from typing import Optional, List, Dict, Tuple
4
+ from chemchat.db.paths import DEFAULT_DB_PATH
5
+
6
+ DB_VERSION = 3
7
+
8
+ MOLECULES = [
9
+ ('水', 'H2O', 'O', '无机化合物', '最常见溶剂,生命必需。', ['一氧化二氢'], [('molecular_weight', '18.02', 'g/mol', ''), ('melting_point', '0', '°C', ''), ('boiling_point', '100', '°C', ''), ('density', '1.00', 'g/cm³', ''), ('physical_chemical_properties', '无色无味液体。极性分子,氢键。', '', ''), ('personal_protection', '安全', '', ''), ('hazard_treatment', '无危害', '', ''), ('safe_storage', '常温密封', '', '')]),
10
+ ('氧气', 'O2', 'O=O', '无机化合物', '呼吸必需气体。', [], [('molecular_weight', '32.00', 'g/mol', ''), ('melting_point', '-218', '°C', ''), ('boiling_point', '-183', '°C', ''), ('density', '1.429', 'g/L', ''), ('physical_chemical_properties', '无色无味气体。助燃。占空气21%。', '', ''), ('personal_protection', '安全', '', ''), ('hazard_treatment', '无危害', '', ''), ('safe_storage', '钢瓶储存', '', '')]),
11
+ ('氮气', 'N2', 'N#N', '无机化合物', '空气主要成分,约占78%。', [], [('molecular_weight', '28.01', 'g/mol', ''), ('melting_point', '-210', '°C', ''), ('boiling_point', '-196', '°C', ''), ('density', '1.251', 'g/L', ''), ('physical_chemical_properties', '无色无味气体。化学性质不活泼。', '', ''), ('personal_protection', '安全(密闭空间注意窒息)', '', ''), ('hazard_treatment', '窒息时移至通风处', '', ''), ('safe_storage', '钢瓶储存', '', '')]),
12
+ ('氢气', 'H2', '[H][H]', '无机化合物', '最轻气体,清洁能源。', [], [('molecular_weight', '2.016', 'g/mol', ''), ('melting_point', '-259', '°C', ''), ('boiling_point', '-253', '°C', ''), ('density', '0.0899', 'g/L', ''), ('physical_chemical_properties', '无色无味气体。极易燃。', '', ''), ('personal_protection', '远离火源', '', ''), ('hazard_treatment', '火灾时切断气源', '', ''), ('safe_storage', '钢瓶,远离火源和氧化剂', '', '')]),
13
+ ('二氧化碳', 'CO2', 'O=C=O', '无机化合物', '温室气体,干冰源。', ['干冰'], [('molecular_weight', '44.01', 'g/mol', ''), ('melting_point', '-56.6', '°C', '(5.2atm)'), ('boiling_point', '-78.5', '°C', '(升华)'), ('density', '1.977', 'g/L', ''), ('physical_chemical_properties', '无色无味气体。不助燃。固态为干冰。', '', ''), ('personal_protection', '密闭空间注意通风', '', ''), ('hazard_treatment', '窒息时移至通风处', '', ''), ('safe_storage', '钢瓶或高压容器', '', '')]),
14
+ ('一氧化碳', 'CO', '[C-]#[O+]', '无机化合物', '无色有毒气体。', ['煤气'], [('molecular_weight', '28.01', 'g/mol', ''), ('melting_point', '-205', '°C', ''), ('boiling_point', '-191.5', '°C', ''), ('density', '1.250', 'g/L', ''), ('physical_chemical_properties', '无色无味气体。剧毒,与血红蛋白结合。', '', ''), ('personal_protection', '安装CO报警器。通风环境中使用。', '', ''), ('hazard_treatment', '立即移至通风处。吸氧。拨打急救。', '', ''), ('safe_storage', '钢瓶储存,标注有毒', '', '')]),
15
+ ('氨气', 'NH3', 'N', '无机化合物', '刺激性气体,化肥原料。', [], [('molecular_weight', '17.03', 'g/mol', ''), ('melting_point', '-77.7', '°C', ''), ('boiling_point', '-33.3', '°C', ''), ('density', '0.6834', 'g/L', ''), ('physical_chemical_properties', '无色气体,强烈刺激性气味。易溶于水。弱碱性。', '', ''), ('personal_protection', '通风橱。防毒面具。护目镜。', '', ''), ('hazard_treatment', '吸入移至通风处。皮肤用水冲洗。', '', ''), ('safe_storage', '钢瓶。阴凉通风。远离酸类。', '', '')]),
16
+ ('硫酸', 'H2SO4', 'OS(=O)(=O)O', '无机酸', '最重要的工业酸。', ['磺镪水'], [('molecular_weight', '98.08', 'g/mol', ''), ('melting_point', '10', '°C', ''), ('boiling_point', '337', '°C', ''), ('density', '1.84', 'g/cm³', ''), ('physical_chemical_properties', '无色粘稠油状液体。与水混溶放热。强酸性、强脱水性。', '', ''), ('personal_protection', '耐酸手套、护目镜、防酸围裙', '', ''), ('hazard_treatment', '皮肤接触大量水冲洗至少15分钟。溅入眼立即冲洗就医。', '', ''), ('safe_storage', '阴凉通风。远离碱类和金属。不可将水倒入酸中。', '', '')]),
17
+ ('盐酸', 'HCl', 'Cl', '无机酸', '氯化氢水溶液。', [], [('molecular_weight', '36.46', 'g/mol', ''), ('density', '1.19', 'g/cm³', '(浓)'), ('physical_chemical_properties', '无色至淡黄色液体,刺激性气味。强酸性。浓盐酸约37%。', '', ''), ('personal_protection', '防护手套、护目镜。通风橱中操作。', '', ''), ('hazard_treatment', '皮肤接触大量水冲洗', '', ''), ('safe_storage', '密封阴凉。远离碱类。', '', '')]),
18
+ ('硝酸', 'HNO3', 'O[N+](=O)[O-]', '无机酸', '强氧化性酸。', [], [('molecular_weight', '63.01', 'g/mol', ''), ('melting_point', '-42', '°C', ''), ('boiling_point', '83', '°C', ''), ('density', '1.51', 'g/cm³', '(浓)'), ('physical_chemical_properties', '无色发烟液体。强酸性、强氧化性。', '', ''), ('personal_protection', '耐酸手套、护目镜、通风橱', '', ''), ('hazard_treatment', '大量水冲洗', '', ''), ('safe_storage', '棕色瓶。阴凉。远离有机物。', '', '')]),
19
+ ('氢氧化钠', 'NaOH', '[Na+].[OH-]', '无机碱', '最重要的工业碱。', ['烧碱', '火碱', '苛性钠'], [('molecular_weight', '40.00', 'g/mol', ''), ('melting_point', '323.4', '°C', ''), ('density', '2.13', 'g/cm³', ''), ('physical_chemical_properties', '白色片状或颗粒。极强腐蚀性。易潮解。溶于水放热。', '', ''), ('personal_protection', '防护手套、护目镜', '', ''), ('hazard_treatment', '大量水冲洗。不可催吐。', '', ''), ('safe_storage', '密封防潮。远离酸类。', '', '')]),
20
+ ('氢氧化钙', 'Ca(OH)2', '[OH-].[OH-].[Ca+2]', '无机碱', '石灰水主要成分。', ['熟石灰', '消石灰'], [('molecular_weight', '74.09', 'g/mol', ''), ('physical_chemical_properties', '白色粉末。微溶于水。碱性。', '', ''), ('personal_protection', '防护手套', '', ''), ('hazard_treatment', '大量水冲洗', '', ''), ('safe_storage', '密封干燥', '', '')]),
21
+ ('氢氧化钾', 'KOH', '[K+].[OH-]', '无机碱', '强碱。', ['苛性钾'], [('molecular_weight', '56.11', 'g/mol', ''), ('physical_chemical_properties', '白色片状。强碱性。易潮解。', '', ''), ('personal_protection', '防护手套、护目镜', '', ''), ('hazard_treatment', '大量水冲洗', '', ''), ('safe_storage', '密封防潮', '', '')]),
22
+ ('氨水', 'NH3·H2O', 'N', '无机碱', '氨气水溶液。', ['氢氧化铵'], [('molecular_weight', '35.05', 'g/mol', ''), ('physical_chemical_properties', '无色液体,强烈刺激性气味。弱碱性。', '', ''), ('personal_protection', '通风橱。防护手套和护目镜。', '', ''), ('hazard_treatment', '吸入移至通风处。皮肤用水冲洗。入眼冲洗15分钟。', '', ''), ('safe_storage', '密封阴凉。远离酸类。', '', '')]),
23
+ ('氯化钠', 'NaCl', '[Na+].[Cl-]', '无机盐', '食盐的主要成分。', ['食盐'], [('molecular_weight', '58.44', 'g/mol', ''), ('melting_point', '801', '°C', ''), ('density', '2.165', 'g/cm³', ''), ('physical_chemical_properties', '白色立方晶体。易溶于水。味咸。', '', ''), ('personal_protection', '安全', '', ''), ('hazard_treatment', '无害', '', ''), ('safe_storage', '防潮保存', '', '')]),
24
+ ('碳酸钠', 'Na2CO3', '[Na+].[Na+].[O-]C(=O)[O-]', '无机盐', '纯碱/苏打。', ['纯碱', '苏打'], [('molecular_weight', '105.99', 'g/mol', ''), ('melting_point', '851', '°C', ''), ('physical_chemical_properties', '白色粉末或晶体。水溶液碱性。', '', ''), ('personal_protection', '防护手套', '', ''), ('hazard_treatment', '大量水冲洗', '', ''), ('safe_storage', '密封防潮', '', '')]),
25
+ ('碳酸氢钠', 'NaHCO3', '[Na+].OC(=O)[O-]', '无机盐', '小苏打。', ['小苏打', '苏打粉'], [('molecular_weight', '84.01', 'g/mol', ''), ('physical_chemical_properties', '白色细小晶体。微溶于水。加热分解产生CO2。弱碱性。', '', ''), ('personal_protection', '安全', '', ''), ('hazard_treatment', '无害', '', ''), ('safe_storage', '阴凉干燥', '', '')]),
26
+ ('碳酸钙', 'CaCO3', '[Ca+2].[O-]C(=O)[O-]', '无机盐', '石灰石主要成分。', ['石灰石', '大理石'], [('molecular_weight', '100.09', 'g/mol', ''), ('physical_chemical_properties', '白色固体。不溶于水。与酸反应产生CO2。', '', ''), ('personal_protection', '防尘口罩', '', ''), ('hazard_treatment', '无危害', '', ''), ('safe_storage', '干燥保存', '', '')]),
27
+ ('硫酸铜', 'CuSO4', '[Cu+2].[O-]S(=O)(=O)[O-]', '无机盐', '蓝色晶体。', ['胆矾', '蓝矾'], [('molecular_weight', '159.61', 'g/mol', '(无水)'), ('physical_chemical_properties', '五水合物蓝色晶体。溶于水。有毒。', '', ''), ('personal_protection', '防护手套和眼镜', '', ''), ('hazard_treatment', '水冲洗', '', ''), ('safe_storage', '密封阴凉', '', '')]),
28
+ ('高锰酸钾', 'KMnO4', '[K+].[O-][Mn](=O)(=O)=O', '无机盐', '强氧化剂。', ['PP粉', '灰锰氧'], [('molecular_weight', '158.03', 'g/mol', ''), ('physical_chemical_properties', '紫黑色晶体。溶于水呈紫色。强氧化性。', '', ''), ('personal_protection', '防护眼镜和手套', '', ''), ('hazard_treatment', '大量水冲洗', '', ''), ('safe_storage', '阴凉干燥。避光密封。远离有机物。', '', '')]),
29
+ ('二氧化锰', 'MnO2', 'O=[Mn]=O', '无机化合物', '黑色催化剂。', ['软锰矿'], [('molecular_weight', '86.94', 'g/mol', ''), ('physical_chemical_properties', '黑色粉末。不溶于水。催化活性。', '', ''), ('personal_protection', '防尘口罩和手套', '', ''), ('hazard_treatment', '水冲洗', '', ''), ('safe_storage', '密封干燥', '', '')]),
30
+ ('过氧化氢', 'H2O2', 'OO', '无机化合物', '双氧水。', ['双氧水'], [('molecular_weight', '34.01', 'g/mol', ''), ('physical_chemical_properties', '无色液体。不稳定易分解。医用3%。强氧化性。', '', ''), ('personal_protection', '低浓度安全。高浓度戴手套护目镜。', '', ''), ('hazard_treatment', '大量水冲洗', '', ''), ('safe_storage', '棕色瓶避光低温', '', '')]),
31
+ ('氧化铁', 'Fe2O3', 'O=[Fe]O[Fe]=O', '无机化合物', '铁锈主要成分。', ['三氧化二铁', '铁锈'], [('molecular_weight', '159.69', 'g/mol', ''), ('physical_chemical_properties', '红棕色粉末。不溶于水。', '', ''), ('personal_protection', '防尘口罩', '', ''), ('hazard_treatment', '水冲洗', '', ''), ('safe_storage', '干燥保存', '', '')]),
32
+ ('氧化钙', 'CaO', '[Ca]=O', '无机化合物', '生石灰。', ['生石灰'], [('molecular_weight', '56.08', 'g/mol', ''), ('melting_point', '2572', '°C', ''), ('physical_chemical_properties', '白色固体。遇水剧烈放热生成Ca(OH)2。', '', ''), ('personal_protection', '防护手套和护目镜', '', ''), ('hazard_treatment', '大量水冲洗', '', ''), ('safe_storage', '密封干燥', '', '')]),
33
+ ('甲烷', 'CH4', 'C', '有机物', '天然气主要成分。', ['天然气'], [('molecular_weight', '16.04', 'g/mol', ''), ('melting_point', '-182.5', '°C', ''), ('boiling_point', '-161.5', '°C', ''), ('physical_chemical_properties', '无色无味气体。可燃。正四面体结构。', '', ''), ('personal_protection', '远离火源', '', ''), ('hazard_treatment', '切断气源。通风。', '', ''), ('safe_storage', '钢瓶储存', '', '')]),
34
+ ('乙烯', 'C2H4', 'C=C', '有机物', '最简单烯烃。', [], [('molecular_weight', '28.05', 'g/mol', ''), ('boiling_point', '-103.7', '°C', ''), ('physical_chemical_properties', '无色气体。微甜味。可燃。催熟水果。', '', ''), ('personal_protection', '远离火源', '', ''), ('hazard_treatment', '通风', '', ''), ('safe_storage', '钢瓶储存', '', '')]),
35
+ ('乙炔', 'C2H2', 'C#C', '有机物', '最简单炔烃。', ['电石气'], [('molecular_weight', '26.04', 'g/mol', ''), ('boiling_point', '-84', '°C', ''), ('physical_chemical_properties', '无色气体。极易燃。氧炔焰3000°C。', '', ''), ('personal_protection', '远离火源', '', ''), ('hazard_treatment', '通风', '', ''), ('safe_storage', '钢瓶储存,远离火源', '', '')]),
36
+ ('乙醇', 'C2H5OH', 'CCO', '有机物', '俗称酒精。', ['酒精'], [('molecular_weight', '46.07', 'g/mol', ''), ('melting_point', '-114.1', '°C', ''), ('boiling_point', '78.37', '°C', ''), ('density', '0.789', 'g/cm³', ''), ('physical_chemical_properties', '无色透明液体,特殊香味。与水任意混溶。易燃。', '', ''), ('personal_protection', '远离明火。大量操作保持通风。', '', ''), ('hazard_treatment', '皮肤用水冲洗。误食就医。', '', ''), ('safe_storage', '阴凉通风。远离火源。密封保存。', '', '')]),
37
+ ('甲醇', 'CH3OH', 'CO', '有机物', '有毒。', ['木醇', '工业酒精'], [('molecular_weight', '32.04', 'g/mol', ''), ('boiling_point', '64.7', '°C', ''), ('physical_chemical_properties', '无色液体。有毒(损害视神经)。可燃。', '', ''), ('personal_protection', '通风橱。防护手套。远离火源。', '', ''), ('hazard_treatment', '误食极危险!立即就医。', '', ''), ('safe_storage', '阴凉通风。远离火源。标注有毒。', '', '')]),
38
+ ('丙三醇', 'C3H5(OH)3', 'OCC(O)CO', '有机物', '甘油。', ['甘油'], [('molecular_weight', '92.09', 'g/mol', ''), ('melting_point', '17.8', '°C', ''), ('boiling_point', '290', '°C', ''), ('density', '1.261', 'g/cm³', ''), ('physical_chemical_properties', '无色粘稠液体。味甜。吸湿性强。', '', ''), ('personal_protection', '安全', '', ''), ('hazard_treatment', '无害', '', ''), ('safe_storage', '密封防潮', '', '')]),
39
+ ('甲醛', 'HCHO', 'C=O', '有机物', '最简单醛,致癌。', ['福尔马林'], [('molecular_weight', '30.03', 'g/mol', ''), ('boiling_point', '-19', '°C', ''), ('physical_chemical_properties', '无色气体。强烈刺激性。致癌。37%水溶液为福尔马林。', '', ''), ('personal_protection', '通风橱。防毒面具和手套。', '', ''), ('hazard_treatment', '吸入移至通风处。皮肤水洗。', '', ''), ('safe_storage', '密封阴凉。远离火源。', '', '')]),
40
+ ('丙酮', 'CH3COCH3', 'CC(=O)C', '有机物', '常用有机溶剂。', [], [('molecular_weight', '58.08', 'g/mol', ''), ('boiling_point', '56', '°C', ''), ('density', '0.791', 'g/cm³', ''), ('physical_chemical_properties', '无色液体。特殊气味。极易挥发和燃烧。与水混溶。', '', ''), ('personal_protection', '远离火源。通风。防护手套。', '', ''), ('hazard_treatment', '水冲洗', '', ''), ('safe_storage', '阴凉通风。远离火源和氧化剂。', '', '')]),
41
+ ('乙酸', 'CH3COOH', 'CC(=O)O', '有机酸', '醋酸。', ['醋酸', '冰醋酸'], [('molecular_weight', '60.05', 'g/mol', ''), ('melting_point', '16.6', '°C', ''), ('boiling_point', '118', '°C', ''), ('density', '1.049', 'g/cm³', ''), ('physical_chemical_properties', '无色液体。刺激性酸味。与水任意混溶。弱酸。', '', ''), ('personal_protection', '稀溶液安全。浓溶液戴手套护目镜。', '', ''), ('hazard_treatment', '水冲洗。入眼就医。', '', ''), ('safe_storage', '密封阴凉通风。远离氧化剂和碱类。', '', '')]),
42
+ ('苯', 'C6H6', 'c1ccccc1', '有机物', '最简单芳香烃,致癌。', [], [('molecular_weight', '78.11', 'g/mol', ''), ('melting_point', '5.5', '°C', ''), ('boiling_point', '80.1', '°C', ''), ('density', '0.8765', 'g/cm³', ''), ('physical_chemical_properties', '无色液体。芳香气味。易燃。致癌。不溶于水。', '', ''), ('personal_protection', '通风橱。防毒面具。防护手套。', '', ''), ('hazard_treatment', '大量水和肥皂清洗。误食就医。', '', ''), ('safe_storage', '阴凉通风。远离火源。标注有毒致癌。', '', '')]),
43
+ ('甲苯', 'C7H8', 'Cc1ccccc1', '有机物', '常用溶剂。', [], [('molecular_weight', '92.14', 'g/mol', ''), ('melting_point', '-95', '°C', ''), ('boiling_point', '110.6', '°C', ''), ('physical_chemical_properties', '无色液体。类似苯气味。有毒。', '', ''), ('personal_protection', '通风橱。防护手套。', '', ''), ('hazard_treatment', '肥皂水清洗。', '', ''), ('safe_storage', '阴凉通风。远离火源。', '', '')]),
44
+ ('苯酚', 'C6H5OH', 'Oc1ccccc1', '有机物', '石炭酸。', ['石炭酸'], [('molecular_weight', '94.11', 'g/mol', ''), ('melting_point', '40.5', '°C', ''), ('boiling_point', '181.7', '°C', ''), ('physical_chemical_properties', '白色晶体。特殊气味。弱酸性。腐蚀性。', '', ''), ('personal_protection', '防护手套。避免皮肤接触。', '', ''), ('hazard_treatment', '大量水冲洗', '', ''), ('safe_storage', '阴凉密封。远离火源。', '', '')]),
45
+ ('葡萄糖', 'C6H12O6', 'OC[C@H]1O[C@@H](O)[C@H](O)[C@@H](O)[C@H]1O', '有机物', '血糖,能量来源。', [], [('molecular_weight', '180.16', 'g/mol', ''), ('melting_point', '146', '°C', ''), ('physical_chemical_properties', '白色粉末。甜味。易溶于水。还原性糖。', '', ''), ('personal_protection', '安全', '', ''), ('hazard_treatment', '无害', '', ''), ('safe_storage', '干燥保存', '', '')]),
46
+ ('蔗糖', 'C12H22O11', 'O[C@H]1[C@H](O)[C@@H](CO)O[C@@]1(CO)O[C@@H]1[C@H](O)[C@@H](O)[C@H](O)[C@@H](CO)O1', '有机物', '食糖。', ['白糖'], [('molecular_weight', '342.30', 'g/mol', ''), ('physical_chemical_properties', '白色晶体。甜味。易溶于水。无还原性。', '', ''), ('personal_protection', '安全', '', ''), ('hazard_treatment', '无害', '', ''), ('safe_storage', '干燥防潮', '', '')]),
47
+ ('尿素', 'CO(NH2)2', 'NC(=O)N', '有机物', '第一种人工合成有机物。', ['脲'], [('molecular_weight', '60.06', 'g/mol', ''), ('melting_point', '133', '°C', ''), ('physical_chemical_properties', '白色晶体。易溶于水。含氮量46%。', '', ''), ('personal_protection', '安全', '', ''), ('hazard_treatment', '无害', '', ''), ('safe_storage', '干燥保存', '', '')]),
48
+ ('阿司匹林', 'C9H8O4', 'CC(=O)Oc1ccccc1C(=O)O', '有机物', '解热镇痛药。', ['乙酰水杨酸'], [('molecular_weight', '180.16', 'g/mol', ''), ('melting_point', '135', '°C', ''), ('physical_chemical_properties', '白色晶体。微溶于水。酸味。', '', ''), ('personal_protection', '安全', '', ''), ('hazard_treatment', '过量就医', '', ''), ('safe_storage', '阴凉干燥', '', '')]),
49
+ ('咖啡因', 'C8H10N4O2', 'Cn1cnc2n(C)c(=O)n(C)c(=O)c12', '有机物', '中枢神经兴奋剂。', [], [('molecular_weight', '194.19', 'g/mol', ''), ('melting_point', '238', '°C', ''), ('physical_chemical_properties', '白色晶体或粉末。苦味。', '', ''), ('personal_protection', '安全(适量)', '', ''), ('hazard_treatment', '过量就医', '', ''), ('safe_storage', '干燥保存', '', '')]),
50
+ ('扑热息痛', 'C8H9NO2', 'CC(=O)Nc1ccc(O)cc1', '有机物', '常用退烧止痛药。', ['对乙酰氨基酚'], [('molecular_weight', '151.16', 'g/mol', ''), ('melting_point', '169', '°C', ''), ('physical_chemical_properties', '白色晶体。微溶于水。', '', ''), ('personal_protection', '安全', '', ''), ('hazard_treatment', '过量伤肝,就医', '', ''), ('safe_storage', '阴凉干燥', '', '')]),
51
+ ('布洛芬', 'C13H18O2', 'CC(C)Cc1ccc(C(C)C(=O)O)cc1', '有机物', '非甾体抗炎药。', [], [('molecular_weight', '206.28', 'g/mol', ''), ('melting_point', '75', '°C', ''), ('physical_chemical_properties', '白色晶体。不溶于水。', '', ''), ('personal_protection', '安全', '', ''), ('hazard_treatment', '过量就医', '', ''), ('safe_storage', '阴凉干燥', '', '')]),
52
+ ('四氯化碳', 'CCl4', 'ClC(Cl)(Cl)Cl', '有机物', '灭火剂(已禁),溶剂。', [], [('molecular_weight', '153.82', 'g/mol', ''), ('boiling_point', '76.7', '°C', ''), ('density', '1.594', 'g/cm³', ''), ('physical_chemical_properties', '无色液体。甜味。不燃。有毒(损害肝脏)。', '', ''), ('personal_protection', '通风橱。防护手套。', '', ''), ('hazard_treatment', '大量水冲洗', '', ''), ('safe_storage', '密封阴凉', '', '')]),
53
+ ('氯仿', 'CHCl3', 'ClC(Cl)Cl', '有机物', '麻醉剂(已弃用)。', ['三氯甲烷'], [('molecular_weight', '119.38', 'g/mol', ''), ('boiling_point', '61.2', '°C', ''), ('density', '1.489', 'g/cm³', ''), ('physical_chemical_properties', '无色液体。甜味。有毒。致癌。', '', ''), ('personal_protection', '通风橱。防护手套。', '', ''), ('hazard_treatment', '大量水冲洗', '', ''), ('safe_storage', '棕色瓶。阴凉密封。', '', '')]),
54
+ ('氧化铁', 'Fe2O3', 'O=[Fe]O[Fe]=O', '无机化合物', '铁锈主要成分。', ['三氧化二铁', '铁锈'], [('molecular_weight', '159.69', 'g/mol', ''), ('physical_chemical_properties', '红棕色粉末。不溶于水。', '', ''), ('personal_protection', '防尘口罩', '', ''), ('hazard_treatment', '水冲洗', '', ''), ('safe_storage', '干燥保存', '', '')]),
55
+ ('四氧化三铁', 'Fe3O4', 'O=[Fe]O[Fe]O[Fe]=O', '无机化合物', '磁性氧化铁。', ['磁性氧化铁'], [('molecular_weight', '231.53', 'g/mol', ''), ('physical_chemical_properties', '黑色固体。有磁性。', '', ''), ('personal_protection', '安全', '', ''), ('hazard_treatment', '无危害', '', ''), ('safe_storage', '干燥保存', '', '')]),
56
+ ('氧化钙', 'CaO', '[Ca]=O', '无机化合物', '生石灰。', ['生石灰'], [('molecular_weight', '56.08', 'g/mol', ''), ('melting_point', '2572', '°C', ''), ('physical_chemical_properties', '白色固体。遇水剧烈放热生成Ca(OH)2。', '', ''), ('personal_protection', '防护手套和护目镜', '', ''), ('hazard_treatment', '大量水冲洗', '', ''), ('safe_storage', '密封干燥', '', '')]),
57
+ ('硝酸银', 'AgNO3', '[Ag+].[O-][N+](=O)[O-]', '无机盐', '银镜反应试剂。', ['银丹'], [('molecular_weight', '169.87', 'g/mol', ''), ('physical_chemical_properties', '无色晶体。见光分解。氧化性。', '', ''), ('personal_protection', '防护手套和护目镜', '', ''), ('hazard_treatment', '大量水冲洗', '', ''), ('safe_storage', '棕色瓶避光保存', '', '')]),
58
+ ('环己烷', 'C6H12', 'C1CCCCC1', '有机物', '非极性溶剂。', [], [('molecular_weight', '84.16', 'g/mol', ''), ('boiling_point', '80.7', '°C', ''), ('physical_chemical_properties', '无色液体。微甜气味。易燃。', '', ''), ('personal_protection', '远离火源。通风。', '', ''), ('hazard_treatment', '水冲洗', '', ''), ('safe_storage', '阴凉通风。远离火源。', '', '')]),
59
+ ('二氯甲烷', 'CH2Cl2', 'ClCCl', '有机物', '常用有机溶剂。', [], [('molecular_weight', '84.93', 'g/mol', ''), ('boiling_point', '39.6', '°C', ''), ('density', '1.326', 'g/cm³', ''), ('physical_chemical_properties', '无色液体。微甜味。不可燃。低毒。', '', ''), ('personal_protection', '通风。防护手套。', '', ''), ('hazard_treatment', '水冲洗', '', ''), ('safe_storage', '阴凉密封', '', '')]),
60
+ ('乙二醇', 'C2H6O2', 'OCCO', '有机物', '防冻液成分。', ['甘醇'], [('molecular_weight', '62.07', 'g/mol', ''), ('melting_point', '-12.9', '°C', ''), ('boiling_point', '197.3', '°C', ''), ('density', '1.113', 'g/cm³', ''), ('physical_chemical_properties', '无色粘稠液体。味甜。有毒。', '', ''), ('personal_protection', '防护手套', '', ''), ('hazard_treatment', '误食就医', '', ''), ('safe_storage', '密封阴凉', '', '')]),
61
+ ('硫酸钡', 'BaSO4', '[Ba+2].[O-]S(=O)(=O)[O-]', '无机盐', 'X射线造影剂。', ['重晶石'], [('molecular_weight', '233.39', 'g/mol', ''), ('physical_chemical_properties', '白色粉末。极难溶于水。不透X射线。', '', ''), ('personal_protection', '安全(口服造影)', '', ''), ('hazard_treatment', '无害', '', ''), ('safe_storage', '干燥保存', '', '')]),
62
+ ('过氧化钠', 'Na2O2', '[Na+].[Na+].[O-][O-]', '无机化合物', '强氧化剂。', [], [('molecular_weight', '77.98', 'g/mol', ''), ('physical_chemical_properties', '淡黄色粉末。与水和CO2反应放O2。强氧化性。', '', ''), ('personal_protection', '防护手套和护目镜', '', ''), ('hazard_treatment', '大量水冲洗', '', ''), ('safe_storage', '密封干燥。远离有机物。', '', '')]),
63
+ ('氧化铝', 'Al2O3', 'O=[Al]O[Al]=O', '无机化合物', '刚玉/蓝宝石成分。', ['刚玉'], [('molecular_weight', '101.96', 'g/mol', ''), ('melting_point', '2072', '°C', ''), ('physical_chemical_properties', '白色粉末或晶体。极硬。不溶于水。两性氧化物。', '', ''), ('personal_protection', '防尘口罩', '', ''), ('hazard_treatment', '无危害', '', ''), ('safe_storage', '干燥保存', '', '')]),
64
+ ('重铬酸钾', 'K2Cr2O7', '[K+].[K+].[O-]Cr(=O)(=O)O[Cr](=O)(=O)[O-]', '无机化合物', '强氧化剂。', [], [('molecular_weight', '294.19', 'g/mol', ''), ('physical_chemical_properties', '橙红色晶体。溶于水。强氧化性。有毒(六价铬)。', '', ''), ('personal_protection', '防护手套。避免皮肤接触。', '', ''), ('hazard_treatment', '大量水冲洗', '', ''), ('safe_storage', '阴凉干燥。远离有机物。', '', '')]),
65
+ ('硫代硫酸钠', 'Na2S2O3', '[Na+].[Na+].[O-]S(=O)(=O)[S-]', '无机盐', '大苏打/海波。', ['大苏打', '海波'], [('molecular_weight', '158.11', 'g/mol', ''), ('physical_chemical_properties', '无色晶体。溶于水。还原性。', '', ''), ('personal_protection', '安全', '', ''), ('hazard_treatment', '无害', '', ''), ('safe_storage', '阴凉密封', '', '')]),
66
+ ('氯化铵', 'NH4Cl', '[NH4+].[Cl-]', '无机盐', '干电池成分。', ['硇砂'], [('molecular_weight', '53.49', 'g/mol', ''), ('physical_chemical_properties', '白色晶体。易溶于水。加热分解。', '', ''), ('personal_protection', '防尘口罩', '', ''), ('hazard_treatment', '水冲洗', '', ''), ('safe_storage', '密封阴凉', '', '')]),
67
+ ('甘氨酸', 'C2H5NO2', 'NCC(=O)O', '有机物', '最简单氨基酸。', [], [('molecular_weight', '75.03', 'g/mol', ''), ('melting_point', '233', '°C', ''), ('physical_chemical_properties', '白色晶体。甜味。两性。', '', ''), ('personal_protection', '安全', '', ''), ('hazard_treatment', '无害', '', ''), ('safe_storage', '干燥保存', '', '')]),
68
+ ]
69
+
70
+
71
+ def init_db(db_path=None):
72
+ db_path = db_path or DEFAULT_DB_PATH
73
+ conn = sqlite3.connect(db_path)
74
+ cur = conn.cursor()
75
+
76
+ cur.execute("PRAGMA user_version")
77
+ ver = cur.fetchone()[0]
78
+
79
+ cur.execute("""CREATE TABLE IF NOT EXISTS molecules(
80
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
81
+ name TEXT NOT NULL UNIQUE,
82
+ formula TEXT NOT NULL,
83
+ smiles TEXT DEFAULT '',
84
+ category TEXT DEFAULT '',
85
+ description TEXT DEFAULT ''
86
+ )""")
87
+ cur.execute("""CREATE TABLE IF NOT EXISTS properties(
88
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
89
+ molecule_id INTEGER NOT NULL,
90
+ property_name TEXT NOT NULL,
91
+ property_value TEXT DEFAULT '',
92
+ unit TEXT DEFAULT '',
93
+ note TEXT DEFAULT '',
94
+ FOREIGN KEY(molecule_id) REFERENCES molecules(id)
95
+ )""")
96
+ cur.execute("""CREATE TABLE IF NOT EXISTS aliases(
97
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
98
+ molecule_id INTEGER NOT NULL,
99
+ alias TEXT NOT NULL,
100
+ FOREIGN KEY(molecule_id) REFERENCES molecules(id)
101
+ )""")
102
+
103
+ cur.execute("PRAGMA table_info(molecules)")
104
+ cols = {row[1] for row in cur.fetchall()}
105
+ if 'smiles' not in cols:
106
+ cur.execute("ALTER TABLE molecules ADD COLUMN smiles TEXT DEFAULT ''")
107
+
108
+ for entry in MOLECULES:
109
+ name = entry[0]
110
+ formula = entry[1]
111
+ smiles = entry[2]
112
+ category = entry[3]
113
+ desc = entry[4]
114
+ aliases = entry[5]
115
+ props = entry[6]
116
+
117
+ cur.execute("SELECT id FROM molecules WHERE name=? OR formula=?", (name, formula))
118
+ row = cur.fetchone()
119
+ if row:
120
+ mid = row[0]
121
+ cur.execute("UPDATE molecules SET smiles=? WHERE id=?", (smiles, mid))
122
+ else:
123
+ cur.execute("INSERT INTO molecules(name,formula,smiles,category,description) VALUES(?,?,?,?,?)",
124
+ (name, formula, smiles, category, desc))
125
+ mid = cur.lastrowid
126
+
127
+ cur.execute("DELETE FROM properties WHERE molecule_id=?", (mid,))
128
+ for pn, pv, unit, note in props:
129
+ cur.execute("INSERT INTO properties(molecule_id,property_name,property_value,unit,note) VALUES(?,?,?,?,?)",
130
+ (mid, pn, pv, unit, note))
131
+
132
+ cur.execute("DELETE FROM aliases WHERE molecule_id=?", (mid,))
133
+ for a in aliases:
134
+ cur.execute("INSERT INTO aliases(molecule_id,alias) VALUES(?,?)", (mid, a))
135
+
136
+ conn.commit()
137
+ cur.execute("SELECT COUNT(*) FROM molecules")
138
+ total = cur.fetchone()[0]
139
+
140
+ cur.execute(f"PRAGMA user_version = {DB_VERSION}")
141
+ conn.commit()
142
+ conn.close()
143
+ return total
144
+
145
+
146
+ def get_all_molecules(db_path=None) -> List[Dict]:
147
+ db_path = db_path or DEFAULT_DB_PATH
148
+ conn = sqlite3.connect(db_path)
149
+ conn.row_factory = sqlite3.Row
150
+ cur = conn.cursor()
151
+ cur.execute("SELECT * FROM molecules ORDER BY id")
152
+ rows = cur.fetchall()
153
+ result = [dict(r) for r in rows]
154
+ conn.close()
155
+ return result
156
+
157
+
158
+ def search_molecules(query: str, db_path=None) -> List[Dict]:
159
+ db_path = db_path or DEFAULT_DB_PATH
160
+ conn = sqlite3.connect(db_path)
161
+ conn.row_factory = sqlite3.Row
162
+ cur = conn.cursor()
163
+ cur.execute("""SELECT m.* FROM molecules m
164
+ LEFT JOIN aliases a ON m.id = a.molecule_id
165
+ WHERE m.name LIKE ? OR m.formula LIKE ? OR m.smiles LIKE ? OR m.category LIKE ? OR a.alias LIKE ?
166
+ ORDER BY m.id""", (f"%{query}%",) * 5)
167
+ rows = cur.fetchall()
168
+ result = [dict(r) for r in rows]
169
+ conn.close()
170
+ return result
171
+
172
+
173
+ def add_molecule(name: str, formula: str, smiles: str = "", category: str = "",
174
+ description: str = "", aliases: List[str] = None,
175
+ properties: List[Tuple] = None, db_path=None) -> int:
176
+ conn = sqlite3.connect(db_path)
177
+ cur = conn.cursor()
178
+ cur.execute("INSERT OR REPLACE INTO molecules(name,formula,smiles,category,description) VALUES(?,?,?,?,?)",
179
+ (name, formula, smiles, category, description))
180
+ mid = cur.lastrowid
181
+ if aliases:
182
+ for a in aliases:
183
+ cur.execute("INSERT INTO aliases(molecule_id,alias) VALUES(?,?)", (mid, a))
184
+ if properties:
185
+ for pn, pv, unit, note in properties:
186
+ cur.execute("INSERT INTO properties(molecule_id,property_name,property_value,unit,note) VALUES(?,?,?,?,?)",
187
+ (mid, pn, pv, unit, note))
188
+ conn.commit()
189
+ conn.close()
190
+ return mid
191
+
192
+
193
+ def update_molecule(mid: int, fields: Dict, db_path=None):
194
+ db_path = db_path or DEFAULT_DB_PATH
195
+ conn = sqlite3.connect(db_path)
196
+ cur = conn.cursor()
197
+ sets = ", ".join(f"{k}=?" for k in fields.keys())
198
+ vals = list(fields.values()) + [mid]
199
+ cur.execute(f"UPDATE molecules SET {sets} WHERE id=?", vals)
200
+ conn.commit()
201
+ conn.close()
202
+
203
+
204
+ def delete_molecule(mid: int, db_path=None):
205
+ db_path = db_path or DEFAULT_DB_PATH
206
+ conn = sqlite3.connect(db_path)
207
+ cur = conn.cursor()
208
+ cur.execute("DELETE FROM properties WHERE molecule_id=?", (mid,))
209
+ cur.execute("DELETE FROM aliases WHERE molecule_id=?", (mid,))
210
+ cur.execute("DELETE FROM molecules WHERE id=?", (mid,))
211
+ conn.commit()
212
+ conn.close()
213
+
214
+
215
+ def export_to_json(filepath: str, db_path=None):
216
+ db_path = db_path or DEFAULT_DB_PATH
217
+ conn = sqlite3.connect(db_path)
218
+ conn.row_factory = sqlite3.Row
219
+ cur = conn.cursor()
220
+ cur.execute("SELECT * FROM molecules ORDER BY id")
221
+ molecules = []
222
+ for row in cur.fetchall():
223
+ m = dict(row)
224
+ mid = m['id']
225
+ cur2 = conn.cursor()
226
+ cur2.execute("SELECT property_name,property_value,unit,note FROM properties WHERE molecule_id=?", (mid,))
227
+ m['properties'] = [dict(r) for r in cur2.fetchall()]
228
+ cur2.execute("SELECT alias FROM aliases WHERE molecule_id=?", (mid,))
229
+ m['aliases'] = [r['alias'] for r in cur2.fetchall()]
230
+ molecules.append(m)
231
+ conn.close()
232
+ import json
233
+ with open(filepath, 'w', encoding='utf-8') as f:
234
+ json.dump(molecules, f, ensure_ascii=False, indent=2)
235
+ return len(molecules)
236
+
237
+
238
+ def export_to_csv(filepath: str, db_path=None):
239
+ db_path = db_path or DEFAULT_DB_PATH
240
+ conn = sqlite3.connect(db_path)
241
+ cur = conn.cursor()
242
+ cur.execute("SELECT name,formula,smiles,category,description FROM molecules ORDER BY id")
243
+ rows = cur.fetchall()
244
+ conn.close()
245
+ with open(filepath, 'w', newline='', encoding='utf-8-sig') as f:
246
+ w = csv.writer(f)
247
+ w.writerow(['name', 'formula', 'smiles', 'category', 'description'])
248
+ w.writerows(rows)
249
+ return len(rows)
250
+
251
+
252
+ def import_from_json(filepath: str, db_path=None) -> int:
253
+ db_path = db_path or DEFAULT_DB_PATH
254
+ import json
255
+ with open(filepath, 'r', encoding='utf-8') as f:
256
+ data = json.load(f)
257
+ count = 0
258
+ for m in data:
259
+ name = m.get('name', '')
260
+ formula = m.get('formula', '')
261
+ smiles = m.get('smiles', '')
262
+ category = m.get('category', '')
263
+ desc = m.get('description', '')
264
+ aliases = m.get('aliases', [])
265
+ props = [(p.get('property_name', ''), p.get('property_value', ''),
266
+ p.get('unit', ''), p.get('note', '')) for p in m.get('properties', [])]
267
+ add_molecule(name, formula, smiles, category, desc, aliases, props, db_path)
268
+ count += 1
269
+ return count
270
+
271
+
272
+ def import_from_csv(filepath: str, db_path=None) -> int:
273
+ db_path = db_path or DEFAULT_DB_PATH
274
+ count = 0
275
+ with open(filepath, 'r', encoding='utf-8-sig') as f:
276
+ reader = csv.DictReader(f)
277
+ for row in reader:
278
+ add_molecule(row['name'], row['formula'], row.get('smiles', ''),
279
+ row.get('category', ''), row.get('description', ''), db_path=db_path)
280
+ count += 1
281
+ return count