12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013 |
- """
- 数据模型核心业务逻辑模块
- 本模块包含了数据模型相关的所有核心业务逻辑函数,包括:
- - 数据模型的创建、更新、删除
- - 数据模型与数据资源、元数据之间的关系处理
- - 数据模型血缘关系管理
- - 数据模型图谱生成
- - 数据模型层级计算等功能
- """
- import math
- import threading
- from concurrent.futures import ThreadPoolExecutor
- import pandas as pd
- from py2neo import Relationship
- import logging
- import json
- from app.core.graph.graph_operations import relationship_exists
- from app.core.graph.graph_operations import connect_graph,create_or_get_node,get_node
- from app.services.neo4j_driver import neo4j_driver
- from app.core.meta_data import get_formatted_time, handle_id_unstructured
- from app.core.common import delete_relationships, update_or_create_node, get_node_by_id_no_label
- from app.core.data_resource.resource import get_node_by_id
- # 根据child关系计算数据模型当前的level自动保存
- def calculate_model_level(id):
- """
- 根据child关系计算数据模型当前的level并自动保存
-
- Args:
- id: 数据模型的节点ID(整数)
-
- Returns:
- None
- """
- # 确保id是整数类型
- node_id = int(id) if id is not None else None
-
- cql = """
- MATCH (start_node:data_model)
- WHERE id(start_node) = $nodeId
- CALL {
- WITH start_node
- OPTIONAL MATCH path = (start_node)-[:child*]->(end_node)
- RETURN length(path) AS level
- }
- WITH coalesce(max(level), 0) AS max_level
- RETURN max_level
- """
-
- with connect_graph().session() as session:
- result = session.run(cql, nodeId=node_id)
- record = result.single()
- data = record["max_level"] if record and "max_level" in record else 0
-
- # 更新level属性
- update_query = """
- MATCH (n:data_model)
- WHERE id(n) = $nodeId
- SET n.level = $level
- RETURN n
- """
- session.run(update_query, nodeId=node_id, level=data)
- # 处理数据模型血缘关系
- def handle_model_relation(resource_ids):
- """
- 处理数据模型血缘关系
-
- Args:
- resource_ids: 数据资源ID
-
- Returns:
- 血缘关系数据
- """
- query = """
- MATCH (search:data_resource)-[:connection]->(common_node:meta_node)<-[:connection]-(connect:data_resource)
- WHERE id(search) = $resource_Ids
- WITH search, connect, common_node
- MATCH (search)-[:connection]->(search_node:meta_node)
- WITH search, connect, common_node, collect(DISTINCT id(search_node)) AS search_nodes
- MATCH (connect)-[:connection]->(connect_node:meta_node)
- WITH search, connect, common_node, search_nodes, collect(DISTINCT id(connect_node)) AS connect_nodes
- WITH search, connect, search_nodes, connect_nodes, collect(DISTINCT id(common_node)) AS common_nodes
- // 剔除 search_nodes 和 connect_nodes 中包含在 common_nodes 中的内容
- WITH search, connect, common_nodes,
- [node IN search_nodes WHERE NOT node IN common_nodes] AS filtered_search_nodes,
- [node IN connect_nodes WHERE NOT node IN common_nodes] AS filtered_connect_nodes
- RETURN id(connect) as blood_resources, common_nodes,
- filtered_search_nodes as origin_nodes, filtered_connect_nodes as blood_nodes
- """
- with connect_graph().session() as session:
- result = session.run(query, resource_Ids=resource_ids)
- return result.data()
- # 创建一个数据模型节点
- def handle_data_model(data_model, result_list, result, receiver):
- """
- 创建一个数据模型节点
-
- Args:
- data_model: 数据模型名称
- result_list: 数据模型英文名列表
- result: 序列化的ID列表
- receiver: 接收到的请求参数
-
- Returns:
- tuple: (id, data_model_node)
- """
- # 添加数据资源 血缘关系的字段 blood_resource
- data_model_en = result_list[0] if result_list and len(result_list) > 0 else ""
- receiver['id_list'] = result
- add_attribute = {
- 'time': get_formatted_time(),
- 'en_name': data_model_en
- }
- receiver.update(add_attribute)
- data_model_node = get_node('data_model', name=data_model) or create_or_get_node('data_model', **receiver)
- child_list = receiver.get('childrenId', [])
- for child_id in child_list:
- child_node = get_node_by_id_no_label(child_id)
- if child_node and not relationship_exists(data_model_node, 'child', child_node):
- with connect_graph().session() as session:
- relationship = Relationship(data_model_node, 'child', child_node)
- session.execute_write(
- lambda tx: tx.run(
- "MATCH (a), (b) WHERE id(a) = $a_id AND id(b) = $b_id CREATE (a)-[:child]->(b)",
- a_id=data_model_node.id, b_id=child_node.id
- )
- )
- # 根据传入参数id,和数据标签建立关系
- if receiver.get('tag'):
- # 使用 Cypher 查询通过 id 查找节点
- tag = get_node_by_id('data_label', receiver['tag'])
- if tag and not relationship_exists(data_model_node, 'label', tag):
- with connect_graph().session() as session:
- session.execute_write(
- lambda tx: tx.run(
- "MATCH (a), (b) WHERE id(a) = $a_id AND id(b) = $b_id CREATE (a)-[:label]->(b)",
- a_id=data_model_node.id, b_id=tag.id
- )
- )
- # 获取节点ID
- node_id = None
- if hasattr(data_model_node, 'id'):
- node_id = data_model_node.id
- else:
- # 如果节点没有id属性,尝试通过查询获取
- query = """
- MATCH (n:data_model {name: $name})
- RETURN id(n) as node_id
- """
- with connect_graph().session() as session:
- result = session.run(query, name=data_model)
- record = result.single()
- if record and "node_id" in record:
- node_id = record["node_id"]
- return node_id, data_model_node
- # (从数据资源中选取)
- def resource_handle_meta_data_model(id_lists, data_model_node_id):
- """
- 处理从数据资源中选取的数据模型与元数据的关系
-
- Args:
- id_lists: ID列表
- data_model_node_id: 数据模型节点ID
-
- Returns:
- None
- """
- # 构建meta_id和resouce_id的列表
- resouce_ids = [record['resource_id'] for record in id_lists]
- meta_ids = [record['id'] for id_list in id_lists for record in id_list['metaData']]
- metaData = [record['data_standard'] for id_list in id_lists for record in id_list['metaData']]
-
- # 创建与meta_node的关系 组成关系
- if meta_ids:
- query = """
- MATCH (source:data_model), (target:meta_node)
- WHERE id(source)=$source_id AND id(target) IN $target_ids
- MERGE (source)-[:component]->(target)
- """
- with neo4j_driver.get_session() as session:
- session.run(query, source_id=data_model_node_id, target_ids=meta_ids)
- # 创建与data_resource的关系 资源关系
- if resouce_ids:
- query = """
- MATCH (source:data_model), (target:data_resource)
- WHERE id(source)=$source_id AND id(target) IN $target_ids
- MERGE (source)-[:resource]->(target)
- """
- with neo4j_driver.get_session() as session:
- session.run(query, source_id=data_model_node_id, target_ids=resouce_ids)
- # (从数据模型中选取)
- def model_handle_meta_data_model(id_lists, data_model_node_id):
- """
- 处理从数据模型中选取的数据模型与元数据的关系
-
- Args:
- id_lists: ID列表
- data_model_node_id: 数据模型节点ID
-
- Returns:
- None
- """
- # 构建meta_id和model_id的列表
- model_ids = [record['model_id'] for record in id_lists]
- meta_ids = [record['id'] for id_list in id_lists for record in id_list['metaData']]
-
- # 创建与meta_node的关系 组成关系
- if meta_ids:
- query = """
- MATCH (source:data_model), (target:meta_node)
- WHERE id(source)=$source_id AND id(target) IN $target_ids
- MERGE (source)-[:component]->(target)
- """
- with neo4j_driver.get_session() as session:
- session.run(query, source_id=data_model_node_id, target_ids=meta_ids)
- # 创建与data_model的关系 模型关系
- if model_ids:
- query = """
- MATCH (source:data_model), (target:data_model)
- WHERE id(source)=$source_id AND id(target) IN $target_ids
- MERGE (source)-[:use]->(target)
- """
- with neo4j_driver.get_session() as session:
- session.run(query, source_id=data_model_node_id, target_ids=model_ids)
- # (从DDL中选取)
- def handle_no_meta_data_model(id_lists, receiver, data_model_node):
- """
- 处理从DDL中选取的没有元数据的数据模型
-
- Args:
- id_lists: ID列表
- receiver: 接收到的请求参数
- data_model_node: 数据模型节点
-
- Returns:
- None
- """
- # 构建meta_id和resouce_id的列表
- resouce_ids = [record['resource_id'] for record in id_lists]
- meta_ids = [record['id'] for id_list in id_lists for record in id_list['metaData']]
-
- # 获取数据模型节点ID
- data_model_node_id = None
- if hasattr(data_model_node, 'id'):
- data_model_node_id = data_model_node.id
- else:
- # 如果节点没有id属性,尝试通过查询获取
- query = """
- MATCH (n:data_model {name: $name})
- RETURN id(n) as node_id
- """
- with connect_graph().session() as session:
- result = session.run(query, name=data_model_node.get('name'))
- record = result.single()
- if record:
- data_model_node_id = record["node_id"]
-
- if not data_model_node_id:
- return
-
- # 创建与data_resource的关系 资源关系
- if resouce_ids:
- query = """
- MATCH (source:data_model), (target:data_resource)
- WHERE id(source)=$source_id AND id(target) IN $target_ids
- MERGE (source)-[:resource]->(target)
- """
- with connect_graph().session() as session:
- session.run(query, source_id=data_model_node_id, target_ids=resouce_ids)
- if meta_ids:
- meta_node_list = []
- for id in meta_ids:
- query = """
- MATCH (n)
- WHERE id(n) = $node_id
- RETURN n
- """
- with connect_graph().session() as session:
- result = session.run(query, node_id=id)
- if result:
- record = result.data()
- if record:
- meta_node_list.append(record[0]['n'])
-
- # 提取接收到的数据并创建meta_node节点
- meta_node = None
- resource_ids = []
-
- for item in id_lists:
- resource_id = item['resource_id']
- resource_ids.append(resource_id)
-
- for meta_item in item['metaData']:
- meta_id = meta_item['id']
- data_standard = meta_item.get('data_standard', '')
- en_name_zh = meta_item.get('en_name_zh', '')
- data_name = meta_item.get('data_name', '')
-
- # 使用传递的参数创建meta_node节点
- meta_params = {
- 'name': data_name,
- 'cn_name': en_name_zh,
- 'standard': data_standard,
- 'time': get_formatted_time()
- }
-
- # 创建meta_node节点
- meta_node = create_or_get_node('meta_node', **meta_params)
-
- # 创建与data_model的关系
- if meta_node and not relationship_exists(data_model_node, 'component', meta_node):
- with connect_graph().session() as session:
- session.execute_write(
- lambda tx: tx.run(
- "MATCH (a), (b) WHERE id(a) = $a_id AND id(b) = $b_id CREATE (a)-[:component]->(b)",
- a_id=data_model_node.id, b_id=meta_node.id
- )
- )
- # 数据模型-详情接口
- def handle_id_model(id):
- """
- 处理数据模型详情请求,查询指定ID的数据模型节点的完整信息
-
- Args:
- id: 数据模型节点ID
-
- Returns:
- dict: 包含数据模型完整详情信息的字典
- """
- try:
- # 确保id是整数类型
- node_id = int(id) if id is not None else None
-
- logging.info(f"查询数据模型详情,ID: {node_id}")
-
- # 构建Cypher查询 - 查询模型基本信息和关联节点
- cql = """
- MATCH (n:data_model)
- WHERE id(n) = $nodeId
-
- // 获取与模型关联的资源节点
- OPTIONAL MATCH (n)-[:resource]->(resource:data_resource)
-
- // 获取与模型关联的数据源节点
- OPTIONAL MATCH (n)-[:use]->(source:data_source)
-
- // 获取模型的标签
- OPTIONAL MATCH (n)-[:label]->(tag:data_label)
-
- // 获取模型的下级节点(子节点)
- OPTIONAL MATCH (n)-[:child]->(child:data_model)
-
- // 获取模型关联的元数据节点
- OPTIONAL MATCH (n)-[:component]->(meta:meta_node)
-
- // 收集所有关联节点信息
- WITH n,
- collect(DISTINCT resource) AS resources,
- collect(DISTINCT source) AS sources,
- tag,
- collect(DISTINCT {id: id(child), name: child.name, en_name: child.en_name}) AS children,
- collect(DISTINCT meta) AS meta_nodes
-
- RETURN {
- // 基本信息
- id: id(n),
- name: n.name,
- en_name: n.en_name,
- // 标签信息从tag变量中获取
- label: tag.name,
- time: n.time,
- description: n.description,
- category: n.category,
- level: n.level,
-
- // 标签信息
- tag: CASE
- WHEN tag IS NOT NULL THEN {id: id(tag), name: tag.name}
- ELSE null
- END,
-
- // 关联的资源列表
- resources: [resource IN resources WHERE resource IS NOT NULL | {
- id: id(resource),
- name: resource.name,
- en_name: resource.en_name,
- description: resource.description
- }],
-
- // 关联的数据源列表
- sources: [source IN sources WHERE source IS NOT NULL | {
- id: id(source),
- name: source.name,
- en_name: source.en_name
- }],
-
- // 子节点列表
- children: children,
-
- // 元数据列表
- meta_nodes: [meta IN meta_nodes WHERE meta IS NOT NULL | {
- id: id(meta),
- name: meta.name,
- en_name: meta.en_name,
- data_type: meta.data_type
- }],
-
- // 原始属性
- properties: properties(n)
- } AS result
- """
-
- with connect_graph().session() as session:
- result = session.run(cql, nodeId=node_id)
-
- # 处理查询结果
- record = result.single()
- logging.info(f"获得查询结果---------->>>{record}")
-
- # 直接检查record是否存在,而不是检查"result"键
- if record:
- # 已经包含"result"键,直接获取其值
- data_model = record["result"]
- logging.info(f"成功获取数据模型详情,ID: {node_id}")
- return data_model
- else:
- logging.warning(f"未找到ID为 {node_id} 的数据模型")
- return {}
-
- except Exception as e:
- logging.error(f"获取数据模型详情出错: {str(e)}", exc_info=True)
- return {}
- # 数据模型列表
- def model_list(skip_count, page_size, en_name_filter=None, name_filter=None,
- category=None, tag=None, level=None):
- """
- 获取数据模型列表
-
- Args:
- skip_count: 跳过的数量
- page_size: 页面大小
- en_name_filter: 英文名称过滤条件
- name_filter: 名称过滤条件
- category: 类别过滤条件
- tag: 标签过滤条件
- level: 层级过滤条件
-
- Returns:
- tuple: (数据模型列表, 总数量)
- """
- try:
- # 构建where子句
- where_clause = []
- params = {}
- if name_filter is not None:
- where_clause.append("n.name =~ $name")
- params['name'] = f".*{name_filter}.*"
-
- if en_name_filter is not None:
- where_clause.append("n.en_name =~ $en_name")
- params['en_name'] = f".*{en_name_filter}.*"
- if category is not None:
- where_clause.append("n.category = $category")
- params['category'] = category
- if level is not None:
- where_clause.append("n.level = $level")
- params['level'] = level
- if tag is not None:
- where_clause.append("id(t) = $tag")
- params['tag'] = tag
- # 处理where子句
- where_str = " AND ".join(where_clause)
- if where_str:
- where_str = f"WHERE {where_str}"
-
- # 构建查询
- with connect_graph().session() as session:
- # 计算总数量
- count_query = f"""
- MATCH (n:data_model)
- OPTIONAL MATCH (n)-[:label]->(t)
- {where_str}
- RETURN COUNT(DISTINCT n) AS count
- """
- count_result = session.run(count_query, **params)
- count_record = count_result.single()
- total = count_record['count'] if count_record else 0
- # 查询数据
- query = f"""
- MATCH (n:data_model)
- OPTIONAL MATCH (n)-[:label]->(t)
- {where_str}
- RETURN DISTINCT
- id(n) as id,
- n.name as name,
- n.en_name as en_name,
- n.time as time,
- n.description as description,
- n.level as level,
- id(t) as tag_id,
- t.name as tag_name
- ORDER BY n.time DESC
- SKIP $skip
- LIMIT $limit
- """
-
- result = session.run(query, skip=skip_count, limit=page_size, **params)
-
- # 处理结果
- data = []
- for record in result:
- item = {
- "id": record['id'],
- "name": record['name'],
- "en_name": record['en_name'],
- "time": record['time'],
- "description": record['description'],
- "level": record['level'],
- "tag": {"id": record['tag_id'], "name": record['tag_name']} if record['tag_id'] is not None else None
- }
- data.append(item)
-
- return data, total
- except Exception as e:
- print(f"Error in model_list: {str(e)}")
- import traceback
- traceback.print_exc()
- return [], 0
- # 有血缘关系的数据资源列表
- def model_resource_list(skip_count, page_size, name_filter=None, id=None,
- category=None, time=None):
- """
- 获取数据模型相关的数据资源列表
-
- Args:
- skip_count: 跳过的数量
- page_size: 页面大小
- name_filter: 名称过滤条件
- id: 数据模型ID
- category: 类别过滤条件
- time: 时间过滤条件
-
- Returns:
- tuple: (数据资源列表, 总数量)
- """
- try:
- # 构建基础查询
- base_query = """
- MATCH (n:data_model)
- WHERE id(n) = $nodeId
- MATCH (n)-[:children]->(m:data_resource)
- """
-
- # 计算总数量
- count_query = base_query + """
- RETURN COUNT(m) as count
- """
-
- with connect_graph().session() as session:
- # 执行计数查询
- count_result = session.run(count_query, nodeId=id)
- count_record = count_result.single()
- total = count_record['count'] if count_record else 0
-
- # 使用分页和筛选条件构建主查询
- main_query = base_query + """
- MATCH (m)-[:label]->(l)
- WHERE id(n) = $nodeId and labels(m) <> ['meta_node']
- RETURN m.name as name,
- m.en_name as en_name,
- id(m) as id,
- l.name as label,
- m.time as time,
- m.description as description,
- m.category as category
- ORDER BY m.time DESC
- SKIP $skip LIMIT $limit
- """
-
- # 执行主查询
- result = session.run(main_query, nodeId=id, skip=skip_count, limit=page_size)
-
- # 处理结果
- data = []
- for record in result:
- item = {
- "name": record['name'],
- "en_name": record['en_name'],
- "id": record['id'],
- "label": record['label'],
- "time": record['time'],
- "description": record['description'],
- "category": record['category']
- }
- data.append(item)
-
- return data, total
- except Exception as e:
- print(f"Error in model_resource_list: {str(e)}")
- import traceback
- traceback.print_exc()
- return [], 0
- # 数据模型血缘图谱
- def model_kinship_graph(nodeid, meta=False):
- """
- 生成数据模型的血缘关系图谱
-
- Args:
- nodeid: 节点ID
- meta: 是否包含元数据
-
- Returns:
- dict: 包含节点和连线信息的图谱数据
- """
- result = {}
-
- with connect_graph().session() as session:
- # 查询起始模型节点
- start_node_query = """
- MATCH (n:data_model)
- WHERE id(n) = $nodeId
- RETURN n.name as name, n.en_name as en_name
- """
-
- start_result = session.run(start_node_query, nodeId=nodeid)
- start_record = start_result.single()
-
- if not start_record:
- return {"nodes": [], "lines": []}
-
- # 查询与模型关联的数据资源
- resource_query = """
- MATCH (n:data_model)
- WHERE id(n) = $nodeId
- MATCH p = (n)-[:children]->(resource:data_resource)
- RETURN resource
- """
-
- resource_result = session.run(resource_query, nodeId=nodeid)
-
- nodes = [{"id": str(nodeid), "text": start_record['name'], "type": "model"}]
- lines = []
-
- # 处理资源节点
- for record in resource_result:
- if 'resource' in record:
- resource = record['resource']
- resource_id = str(resource.id)
- resource_name = resource.get('name', '')
- resource_en_name = resource.get('en_name', '')
-
- # 创建资源节点
- resource_node = {
- "id": resource_id,
- "text": resource_name,
- "type": "resource"
- }
- nodes.append(resource_node)
-
- # 创建资源到模型的关系
- line = {
- "from": str(nodeid),
- "to": resource_id,
- "text": "resource"
- }
- lines.append(line)
- # 处理元数据节点
- if meta:
- meta_query = """
- MATCH (n:data_model)
- WHERE id(n) = $nodeId and labels(m) <> ['meta_node']
- MATCH p = (n)-[:meta]->(meta:meta_node)
- RETURN meta
- """
- meta_result = session.run(meta_query, nodeId=nodeid)
-
- for record in meta_result:
- if 'meta' in record:
- meta_node = record['meta']
- meta_id = str(meta.id)
- meta_name = meta.get('name', '')
- meta_en_name = meta.get('en_name', '')
-
- # 创建元数据节点
- meta_node = {
- "id": meta_id,
- "text": meta_name,
- "type": "meta"
- }
- nodes.append(meta_node)
-
- # 创建模型到元数据的标签关系
- tag_line = {
- "from": str(nodeid),
- "to": meta_id,
- "text": "component"
- }
- lines.append(tag_line)
- # 构建结果
- result = {
- "nodes": nodes,
- "lines": lines
- }
- return result
- # 数据模型影响图谱
- def model_impact_graph(nodeid, meta=False):
- """
- 生成数据模型的影响关系图谱
-
- Args:
- nodeid: 节点ID
- meta: 是否包含元数据
-
- Returns:
- dict: 包含节点和连线信息的图谱数据
- """
- result = {}
-
- with connect_graph().session() as session:
- # 查询起始模型节点
- start_node_query = """
- MATCH (n:data_model)
- WHERE id(n) = $nodeId
- RETURN n.name as name, n.en_name as en_name
- """
-
- start_result = session.run(start_node_query, nodeId=nodeid)
- start_record = start_result.single()
-
- if not start_record:
- return {"nodes": [], "lines": []}
-
- # 查询影响模型的数据资源
- resource_query = """
- MATCH (n:data_model)
- WHERE id(n) = $nodeId
- MATCH p = (n)-[:children]->(resource:data_resource)
- RETURN resource
- """
-
- resource_result = session.run(resource_query, nodeId=nodeid)
-
- nodes = [{"id": str(nodeid), "text": start_record['name'], "type": "model"}]
- lines = []
-
- # 处理资源节点
- for record in resource_result:
- if 'resource' in record:
- resource = record['resource']
- resource_id = str(resource.id)
- resource_name = resource.get('name', '')
- resource_en_name = resource.get('en_name', '')
-
- # 创建资源节点
- resource_node = {
- "id": resource_id,
- "text": resource_name,
- "type": "resource"
- }
- nodes.append(resource_node)
-
- # 创建资源到模型的关系
- line = {
- "from": str(nodeid),
- "to": resource_id,
- "text": "resource"
- }
- lines.append(line)
- # 处理元数据节点
- if meta:
- meta_query = """
- MATCH (n:data_model)
- WHERE id(n) = $nodeId and labels(m) <> ['meta_node']
- MATCH p = (n)-[:meta]->(meta:meta_node)
- RETURN meta
- """
- meta_result = session.run(meta_query, nodeId=nodeid)
-
- for record in meta_result:
- if 'meta' in record:
- meta_node = record['meta']
- meta_id = str(meta.id)
- meta_name = meta.get('name', '')
- meta_en_name = meta.get('en_name', '')
-
- # 创建元数据节点
- meta_node = {
- "id": meta_id,
- "text": meta_name,
- "type": "meta"
- }
- nodes.append(meta_node)
-
- # 创建模型到元数据的标签关系
- tag_line = {
- "from": str(nodeid),
- "to": meta_id,
- "text": "component"
- }
- lines.append(tag_line)
- # 构建结果
- result = {
- "nodes": nodes,
- "lines": lines
- }
- return result
- # 数据模型全部图谱
- def model_all_graph(nodeid, meta=False):
- """
- 生成数据模型的所有关系图谱
-
- Args:
- nodeid: 节点ID
- meta: 是否包含元数据
-
- Returns:
- dict: 包含节点和连线信息的图谱数据
- """
- result = {}
-
- with connect_graph().session() as session:
- # 查询起始模型节点
- start_node_query = """
- MATCH (n:data_model)
- WHERE id(n) = $nodeId
- RETURN n.name as name, n.en_name as en_name
- """
-
- start_result = session.run(start_node_query, nodeId=nodeid)
- start_record = start_result.single()
-
- if not start_record:
- return {"nodes": [], "lines": []}
-
- # 查询与模型关联的数据资源
- resource_query = """
- MATCH (n:data_model)
- WHERE id(n) = $nodeId
- MATCH p = (n)-[:children]->(resource:data_resource)
- RETURN resource
- """
-
- resource_result = session.run(resource_query, nodeId=nodeid)
-
- # 查询与模型关联的元数据
- meta_query = """
- MATCH (n:data_model)
- WHERE id(n) = $nodeId and labels(m) <> ['meta_node']
- MATCH p = (n)-[:meta]->(meta:meta_node)
- RETURN meta
- """
-
- nodes = [{"id": str(nodeid), "text": start_record['name'], "type": "model"}]
- lines = []
-
- # 处理资源节点
- for record in resource_result:
- if 'resource' in record:
- resource = record['resource']
- resource_id = str(resource.id)
- resource_name = resource.get('name', '')
- resource_en_name = resource.get('en_name', '')
-
- # 创建资源节点
- resource_node = {
- "id": resource_id,
- "text": resource_name,
- "type": "resource"
- }
- nodes.append(resource_node)
-
- # 创建资源到模型的关系
- line = {
- "from": str(nodeid),
- "to": resource_id,
- "text": "resource"
- }
- lines.append(line)
- # 处理元数据节点
- if meta:
- meta_result = session.run(meta_query, nodeId=nodeid)
-
- for record in meta_result:
- if 'meta' in record:
- meta_node = record['meta']
- meta_id = str(meta.id)
- meta_name = meta.get('name', '')
- meta_en_name = meta.get('en_name', '')
-
- # 创建元数据节点
- meta_node = {
- "id": meta_id,
- "text": meta_name,
- "type": "meta"
- }
- nodes.append(meta_node)
-
- # 创建模型到元数据的标签关系
- tag_line = {
- "from": str(nodeid),
- "to": meta_id,
- "text": "component"
- }
- lines.append(tag_line)
- # 构建结果
- result = {
- "nodes": nodes,
- "lines": lines
- }
- return result
- # 更新数据模型
- def data_model_edit(receiver):
- """
- 更新数据模型
-
- Args:
- receiver: 接收到的请求参数
-
- Returns:
- 更新结果
- """
- id = receiver.get('id')
- name = receiver.get('name')
- en_name = receiver.get('en_name')
- category = receiver.get('category')
- description = receiver.get('description')
- tag = receiver.get('tag')
-
- # 更新数据模型节点
- query = """
- MATCH (n:data_model) WHERE id(n) = $id
- SET n.name = $name, n.en_name = $en_name, n.category = $category, n.description = $description
- RETURN n
- """
-
- with connect_graph().session() as session:
- result = session.run(query, id=id, name=name, en_name=en_name,
- category=category, description=description).data()
-
- # 处理标签关系
- if tag:
- # 先删除所有标签关系
- delete_query = """
- MATCH (n:data_model)-[r:label]->() WHERE id(n) = $id
- DELETE r
- """
- with connect_graph().session() as session:
- session.run(delete_query, id=id)
-
- # 再创建新的标签关系
- tag_node = get_node_by_id('data_label', tag)
- if tag_node:
- model_node = get_node_by_id_no_label(id)
- if model_node and not relationship_exists(model_node, 'label', tag_node):
- with connect_graph().session() as session:
- session.execute_write(
- lambda tx: tx.run(
- "MATCH (a), (b) WHERE id(a) = $a_id AND id(b) = $b_id CREATE (a)-[:label]->(b)",
- a_id=model_node.id, b_id=tag_node.id
- )
- )
-
- return {"message": "数据模型更新成功"}
|