方案1:JSON全量存储(最简洁)
数据库模型:
models.py
Apply to models.py
id = Column(Integer, primary_key=True) name = Column(String(200), nullable=False) description = Column(Text, nullable=True) device_id = Column(String(50), ForeignKey('device_tree.device_id'), nullable=False) version = Column(String(20), nullable=False, default='1.0') created_at = Column(String(20), nullable=False) updated_at = Column(String(20), nullable=False)# 存储整个流程图的JSON数据
# ... existing imports ...
class Flowchart(Base):
"""简化的流程图模型"""
__tablename__ = 'flowchart'
flowchart_data = Column(JSON, nullable=True, comment='流程图完整数据')
存储格式:
{ "components": [ { "id": "comp_1", "type": "sensor", "position": {"x": 100, "y": 50}, "data": { "label": "温度传感器", "properties": {"threshold": 50} } } ], "connections": [ { "id": "conn_1", "source": "comp_1", "target": "comp_2", "sourceHandle": "output1", "targetHandle": "input1" } ], "viewport": { "x": 0, "y": 0, "zoom": 1 } }方案2:组件和连接合并存储
数据库模型:
models.py
Apply to models.py
class Flowchart(Base): """流程图""" __tablename__ = 'flowchart' id = Column(Integer, primary_key=True) name = Column(String(200), nullable=False) description = Column(Text, nullable=True) device_id = Column(String(50), ForeignKey('device_tree.device_id'), nullable=False) version = Column(String(20), nullable=False, default='1.0') created_at = Column(String(20), nullable=False) updated_at = Column(String(20), nullable=False) class FlowchartElement(Base): """流程图元素(组件和连接统一存储)""" __tablename__ = 'flowchart_element' id = Column(Integer, primary_key=True) flowchart_id = Column(Integer, ForeignKey('flowchart.id'), nullable=False) element_type = Column(String(20), nullable=False, comment='类型:component/connection') element_id = Column(String(100), nullable=False, comment='元素唯一标识') # 元素数据(JSON格式) data = Column(JSON, nullable=False, comment='元素完整数据') # 关系 flowchart = relationship('Flowchart', backref='elements')存储示例:
-- 组件 INSERT INTO flowchart_element VALUES ( 1, 1, 'component', 'comp_1', '{"type": "sensor", "position": {"x": 100, "y": 50}, "data": {"label": "传感器"}}' ); -- 连接 INSERT INTO flowchart_element VALUES ( 2, 1, 'connection', 'conn_1', '{"source": "comp_1", "target": "comp_2", "sourceHandle": "out1"}' );方案3:文件系统 + 数据库索引
数据库模型:
models.py
Apply to models.py
class Flowchart(Base): """流程图索引""" __tablename__ = 'flowchart' id = Column(Integer, primary_key=True) name = Column(String(200), nullable=False) description = Column(Text, nullable=True) device_id = Column(String(50), ForeignKey('device_tree.device_id'), nullable=False) version = Column(String(20), nullable=False, default='1.0') created_at = Column(String(20), nullable=False) updated_at = Column(String(20), nullable=False) # 文件路径 file_path = Column(String(500), nullable=True, comment='流程图文件路径') file_hash = Column(String(64), nullable=True, comment='文件哈希,用于版本控制')实现方式:
- 流程图数据存储为JSON文件
- 数据库只保存索引和元信息
- 支持大文件存储和版本控制
推荐方案:方案1(JSON全量存储)
这是最简洁的方式,特别适合:
优点:
- 表结构简单:只有一个Flowchart表存储所有数据
- 查询高效:一次查询获取完整流程图
- 灵活扩展:JSON格式支持任意复杂结构
- 版本控制简单:直接比较JSON数据
- 前端集成容易:直接返回前端需要的格式
API实现:
flowchart_api.py
Apply to flowchart_ap...
@flowchart_bp.route('/flowcharts/<int:flowchart_id>', methods=['GET']) def get_flowchart(flowchart_id): """获取流程图""" db = get_db() try: flowchart = db.query(Flowchart).filter(Flowchart.id == flowchart_id).first() if not flowchart: return jsonify({'error': 'Flowchart not found'}), 404 return jsonify({ 'id': flowchart.id, 'name': flowchart.name, 'description': flowchart.description, 'device_id': flowchart.device_id, 'version': flowchart.version, 'created_at': flowchart.created_at, 'updated_at': flowchart.updated_at, 'flowchart_data': flowchart.flowchart_data }) finally: db.close() @flowchart_bp.route('/flowcharts/<int:flowchart_id>', methods=['PUT']) def update_flowchart_data(flowchart_id): """更新流程图数据""" data = request.json db = get_db() try: flowchart = db.query(Flowchart).filter(Flowchart.id == flowchart_id).first() if not flowchart: return jsonify({'error': 'Flowchart not found'}), 404 flowchart.flowchart_data = data.get('flowchart_data') flowchart.updated_at = datetime.now().isoformat() db.commit() return jsonify({'message': 'Flowchart updated'}) except Exception as e: db.rollback() return jsonify({'error': str(e)}), 400 finally: db.close()前端使用:
// 保存流程图 const saveFlowchart = async (flowchartId, flowData) => { await fetch(`/flowcharts/${flowchartId}`, { method: 'PUT', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ flowchart_data: flowData // React Flow的数据格式 }) }); }; // 加载流程图 const loadFlowchart = async (flowchartId) => { const response = await fetch(`/flowcharts/${flowchartId}`); const data = await response.json(); return data.flowchart_data; // 直接返回React Flow格式 };这个方案大大简化了数据库设计,特别适合中小型应用。如果你需要更复杂的查询或关系型操作,可以选择方案2。
方案1 存储格式 怎么理解
Thoughtfor 1s
方案1存储格式详解
方案1使用JSON全量存储,将整个流程图的数据以JSON格式存储在flowchart_data字段中。
存储格式结构
{ "components": [ { "id": "comp_1", "type": "sensor", "position": { "x": 100, "y": 50 }, "data": { "label": "温度传感器", "properties": { "threshold": 50, "unit": "°C", "alarmEnabled": true } }, "style": { "backgroundColor": "#e1f5fe", "borderColor": "#01579b" } }, { "id": "comp_2", "type": "controller", "position": { "x": 300, "y": 50 }, "data": { "label": "PID控制器", "properties": { "kp": 1.0, "ki": 0.1, "kd": 0.05 } } } ], "connections": [ { "id": "conn_1", "source": "comp_1", "target": "comp_2", "sourceHandle": "output1", "targetHandle": "input1", "label": "温度信号", "type": "bezier", "animated": true, "style": { "stroke": "#1890ff", "strokeWidth": 2 }, "data": { "signalType": "analog", "range": "0-100°C" } } ], "viewport": { "x": 0, "y": 0, "zoom": 1.0 }, "metadata": { "version": "1.0", "lastEdited": "2024-01-01T10:00:00Z", "author": "user123" } }字段说明
1. components - 组件数组
每个组件包含:
- id: 组件唯一标识
- type: 组件类型(对应前端节点类型)
- position: 位置坐标 {x, y}
- data: 组件数据
- label: 显示标签
- properties: 组件属性配置
- style: 可选的样式信息
2. connections - 连接数组
每个连接包含:
- id: 连接唯一标识
- source/target: 连接的源/目标组件ID
- sourceHandle/targetHandle: 连接的端口
- label: 连接标签
- type: 连线类型(bezier, straight等)
- data: 连接的额外数据
3. viewport - 画布视口
- x, y: 画布偏移
- zoom: 缩放比例
4. metadata - 元数据
- 版本信息、编辑时间等
与前端集成
React Flow格式映射:
// 后端JSON → React Flow格式
function convertToReactFlow(flowchartData) { return { nodes: flowchartData.components.map(comp => ({ id: comp.id, type: comp.type, position: comp.position, data: comp.data, style: comp.style })), edges: flowchartData.connections.map(conn => ({ id: conn.id, source: conn.source, target: conn.target, sourceHandle: conn.sourceHandle, targetHandle: conn.targetHandle, label: conn.label, type: conn.type, animated: conn.animated, style: conn.style, data: conn.data })), viewport: flowchartData.viewport }; } // React Flow格式 → 后端JSON function convertFromReactFlow(nodes, edges, viewport) { return { components: nodes.map(node => ({ id: node.id, type: node.type, position: node.position, data: node.data, style: node.style })), connections: edges.map(edge => ({ id: edge.id, source: edge.source, target: edge.target, sourceHandle: edge.sourceHandle, targetHandle: edge.targetHandle, label: edge.label, type: edge.type, animated: edge.animated, style: edge.style, data: edge.data })), viewport: viewport, metadata: { version: "1.0", lastEdited: new Date().toISOString() } }; }数据库存储示例
-
- 流程图记录 INSERT INTO flowchart (name, description, device_id, version, created_at, updated_at, flowchart_data) VALUES ( '温度控制流程图', '传感器到控制器的完整流程', 'device_001', '1.0', '2024-01-01T10:00:00', '2024-01-01T10:00:00', '{ "components": [ { "id": "sensor_1", "type": "sensor", "position": {"x": 100, "y": 50}, "data": { "label": "温度传感器", "properties": {"threshold": 50, "unit": "°C"} } } ], "connections": [], "viewport": {"x": 0, "y": 0, "zoom": 1}, "metadata": {"version": "1.0"} }' );前端使用示例
// 加载流程图 async function loadFlowchart(flowchartId) { const response = await fetch(`/flowcharts/${flowchartId}`); const result = await response.json(); // 直接转换为React Flow格式 const flowData = convertToReactFlow(result.flowchart_data); // 设置到React Flow setNodes(flowData.nodes); setEdges(flowData.edges); setViewport(flowData.viewport); } // 保存流程图 async function saveFlowchart(flowchartId, nodes, edges, viewport) { // 转换为后端格式 const flowchartData = convertFromReactFlow(nodes, edges, viewport); await fetch(`/flowcharts/${flowchartId}`, { method: 'PUT', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ flowchart_data: flowchartData }) }); }优点
- 数据完整性:一次存储/加载整个流程图
- 版本控制简单:直接比较JSON字符串
- 前端集成无缝:格式与前端库高度兼容
- 扩展灵活:JSON支持任意结构变化
- 查询高效:单表查询,无需多表关联
适用场景
- 流程图规模不大(JSON大小合理)
- 需要频繁的完整读写操作
- 前端需要直接使用流程图数据
- 对关系型查询需求不复杂
这种格式特别适合与React Flow、Draw.io等前端流程图库集成,因为数据结构高度匹配。