|
@@ -573,11 +573,28 @@ def sql_test():
|
|
|
def ddl_identify():
|
|
|
"""识别DDL语句"""
|
|
|
try:
|
|
|
- # 获取参数
|
|
|
- sql_content = request.json.get('sql', '')
|
|
|
-
|
|
|
+ # 获取参数 - 支持两种方式:上传文件或JSON
|
|
|
+ sql_content = ''
|
|
|
+
|
|
|
+ # 检查是否有文件上传
|
|
|
+ if 'file' in request.files:
|
|
|
+ file = request.files['file']
|
|
|
+ # 检查文件是否存在且文件名不为空
|
|
|
+ if file and file.filename:
|
|
|
+ # 检查是否是SQL文件
|
|
|
+ if not file.filename.lower().endswith('.sql'):
|
|
|
+ return jsonify(failed("只接受SQL文件"))
|
|
|
+
|
|
|
+ # 读取文件内容
|
|
|
+ sql_content = file.read().decode('utf-8')
|
|
|
+ logger.info(f"从上传的文件中读取SQL内容,文件名: {file.filename}")
|
|
|
+ # 如果没有文件上传,检查是否有JSON输入
|
|
|
+ elif request.is_json:
|
|
|
+ sql_content = request.json.get('sql', '')
|
|
|
+
|
|
|
+ # 如果两种方式都没有提供SQL内容,则返回错误
|
|
|
if not sql_content:
|
|
|
- return jsonify(failed("SQL内容不能为空"))
|
|
|
+ return jsonify(failed("SQL内容不能为空,请上传SQL文件或提供SQL内容"))
|
|
|
|
|
|
parser = DDLParser()
|
|
|
# 提取创建表的DDL语句
|
|
@@ -586,13 +603,42 @@ def ddl_identify():
|
|
|
if not ddl_list:
|
|
|
return jsonify(failed("未找到有效的CREATE TABLE语句"))
|
|
|
|
|
|
+ # 创建最终返回结果的结构
|
|
|
+ result = {}
|
|
|
+ data_source = None
|
|
|
+ tables = {}
|
|
|
+
|
|
|
# 为每个表名添加exist字段
|
|
|
if isinstance(ddl_list, dict):
|
|
|
# 检查是否有data_source键
|
|
|
- data_source = None
|
|
|
if "data_source" in ddl_list:
|
|
|
- # 临时移除data_source,以便只遍历表
|
|
|
+ # 提取数据源信息
|
|
|
data_source = ddl_list.pop("data_source", None)
|
|
|
+
|
|
|
+ # 检查数据源是否存在
|
|
|
+ if data_source:
|
|
|
+ # 检查数据源是否包含en_name
|
|
|
+ if "en_name" not in data_source:
|
|
|
+ return jsonify(failed("数据源信息不完整:缺少en_name字段"))
|
|
|
+
|
|
|
+ try:
|
|
|
+ # 使用Neo4j查询检查数据源是否存在
|
|
|
+ data_source_name = data_source["en_name"]
|
|
|
+ # 注意:数据源的标签应该是data_source而不是data_resource
|
|
|
+ with neo4j_driver.get_session() as session:
|
|
|
+ source_query = """
|
|
|
+ MATCH (n:data_source {en_name: $name})
|
|
|
+ RETURN n IS NOT NULL AS exists
|
|
|
+ """
|
|
|
+ source_result = session.run(source_query, name=data_source_name)
|
|
|
+ source_exists = source_result.single()
|
|
|
+ if source_exists:
|
|
|
+ data_source["exist"] = source_exists["exists"]
|
|
|
+ else:
|
|
|
+ data_source["exist"] = False
|
|
|
+ except Exception as e:
|
|
|
+ logger.error(f"检查数据源存在状态失败: {str(e)}")
|
|
|
+ data_source["exist"] = False
|
|
|
|
|
|
# 获取所有表名 - 过滤掉可能的非表结构键
|
|
|
table_names = []
|
|
@@ -600,44 +646,48 @@ def ddl_identify():
|
|
|
# 检查值是否是字典且包含meta键,这表明它是一个表结构
|
|
|
if isinstance(value, dict) and "meta" in value:
|
|
|
table_names.append(key)
|
|
|
+ # 将表信息添加到tables字典中
|
|
|
+ tables[key] = value
|
|
|
# 如果不是表结构,则不处理
|
|
|
|
|
|
- # 只有在有表名时才调用status_query
|
|
|
+ # 只有在有表名时才查询表是否存在
|
|
|
if table_names:
|
|
|
try:
|
|
|
- # 调用status_query获取表的存在状态
|
|
|
- status_results = status_query(table_names)
|
|
|
-
|
|
|
- # status_query返回的可能是单个值或嵌套列表,需要平展处理
|
|
|
- flat_results = []
|
|
|
- if status_results:
|
|
|
- # 如果是嵌套列表(通常只有一层嵌套),则拍平
|
|
|
- if isinstance(status_results, list):
|
|
|
- if len(status_results) == 1 and isinstance(status_results[0], list):
|
|
|
- flat_results = status_results[0] # 拍平一层嵌套
|
|
|
- else:
|
|
|
- flat_results = status_results # 已经是平的列表
|
|
|
-
|
|
|
- # 将状态添加到每个表
|
|
|
- for i, table_name in enumerate(table_names):
|
|
|
- if i < len(flat_results):
|
|
|
- ddl_list[table_name]["exist"] = flat_results[i]
|
|
|
- else:
|
|
|
- ddl_list[table_name]["exist"] = False
|
|
|
-
|
|
|
+ # 在Neo4j中查询表名是否存在于data_resource节点
|
|
|
+ with neo4j_driver.get_session() as session:
|
|
|
+ table_query = """
|
|
|
+ UNWIND $names AS name
|
|
|
+ OPTIONAL MATCH (n:data_resource {en_name: name})
|
|
|
+ RETURN name, n IS NOT NULL AS exists
|
|
|
+ """
|
|
|
+ table_results = session.run(table_query, names=table_names)
|
|
|
+
|
|
|
+ # 处理结果
|
|
|
+ for record in table_results:
|
|
|
+ table_name = record["name"]
|
|
|
+ exists = record["exists"]
|
|
|
+ if table_name in tables:
|
|
|
+ tables[table_name]["exist"] = exists
|
|
|
+
|
|
|
+ # 确保所有表都有exist字段
|
|
|
+ for table_name in table_names:
|
|
|
+ if "exist" not in tables[table_name]:
|
|
|
+ tables[table_name]["exist"] = False
|
|
|
+
|
|
|
except Exception as e:
|
|
|
logger.error(f"检查表存在状态失败: {str(e)}")
|
|
|
- # 如果status_query失败,所有表默认为不存在
|
|
|
+ # 如果查询失败,所有表默认为不存在
|
|
|
for table_name in table_names:
|
|
|
- ddl_list[table_name]["exist"] = False
|
|
|
-
|
|
|
- # 恢复data_source
|
|
|
- if data_source:
|
|
|
- ddl_list["data_source"] = data_source
|
|
|
+ tables[table_name]["exist"] = False
|
|
|
+
|
|
|
+ # 构建最终返回的结构
|
|
|
+ result["tables"] = tables
|
|
|
+ if data_source:
|
|
|
+ result["data_source"] = data_source
|
|
|
|
|
|
- logger.debug(f"识别到的DDL语句: {ddl_list}")
|
|
|
+ logger.debug(f"识别到的DDL语句: {result}")
|
|
|
|
|
|
- return jsonify(success(ddl_list))
|
|
|
+ return jsonify(success(result))
|
|
|
except Exception as e:
|
|
|
logger.error(f"识别DDL语句失败: {str(e)}")
|
|
|
logger.error(traceback.format_exc()) # 添加详细错误堆栈
|