网站建设合作范本佛山键讯科技有限公司
网站建设合作范本,佛山键讯科技有限公司,网站建设技巧饣金手指排名27,怎么查网站有没有做404通义千问1.5-1.8B-Chat-GPTQ-Int4 WebUI 数据库智能查询实战#xff1a;自然语言转SQL语句生成
1. 引言#xff1a;让数据开口说话
想象一下这个场景#xff1a;市场部的同事想了解“上个月销售额最高的前五个产品是什么”#xff0c;他不需要去麻烦技术部门的工程师 USE company_sales; -- 创建一张产品销售表 CREATE TABLE product_sales ( id INT AUTO_INCREMENT PRIMARY KEY, product_name VARCHAR(100) NOT NULL, -- 产品名称 category VARCHAR(50), -- 产品类别 sale_date DATE, -- 销售日期 quantity INT, -- 销售数量 unit_price DECIMAL(10, 2), -- 单价 sales_amount DECIMAL(12, 2) -- 销售额 (quantity * unit_price) ); -- 插入一些示例数据 INSERT INTO product_sales (product_name, category, sale_date, quantity, unit_price, sales_amount) VALUES (无线蓝牙耳机, 电子产品, 2024-05-10, 120, 199.00, 23880.00), (智能手机, 电子产品, 2024-05-15, 85, 2999.00, 254915.00), (办公椅, 家具, 2024-05-08, 30, 450.00, 13500.00), (咖啡机, 厨房电器, 2024-05-12, 45, 899.00, 40455.00), (笔记本电脑, 电子产品, 2024-05-20, 25, 6599.00, 164975.00), (马克杯套装, 日用品, 2024-05-05, 200, 39.90, 7980.00), (智能手表, 电子产品, 2024-05-18, 70, 1299.00, 90930.00);Python环境与依赖库我们的后端服务将使用Python编写。确保你安装了Python 3.8或更高版本。然后通过pip安装必要的库pip install pymysql # 用于连接和操作MySQL数据库 pip install requests # 用于调用通义千问WebUI的HTTP API # 如果后续需要Web界面可能还会用到Flask或FastAPI这里我们先以API服务为核心。3.2 通义千问WebUI服务准备你需要已经部署好通义千问1.5-1.8B-Chat-GPTQ-Int4模型的WebUI服务。通常这类服务会提供一个本地HTTP API端点例如http://localhost:8000/v1/chat/completions。确保该服务正在运行并且你知道其API地址和调用方式一般是模仿OpenAI API格式。4. 核心实现从自然语言到SQL的魔法4.1 第一步获取数据库的“地图”Schema模型要生成正确的SQL必须先知道数据库里有什么。我们需要编写一个函数动态地获取指定数据库的表结构信息。import pymysql from typing import Dict, List, Any def get_database_schema(db_config: Dict[str, Any]) - str: 连接数据库获取所有表的结构信息并格式化为字符串。 返回的字符串将作为Prompt的一部分输入给模型。 schema_description [] try: connection pymysql.connect(**db_config) cursor connection.cursor() # 1. 获取所有表名 cursor.execute(SHOW TABLES) tables cursor.fetchall() for (table_name,) in tables: schema_description.append(f表名: {table_name}) # 2. 获取表的字段信息 cursor.execute(fDESCRIBE {table_name}) columns cursor.fetchall() for col in columns: # col结构: (Field, Type, Null, Key, Default, Extra) field_name, field_type, is_null, key_type, default_val, extra col schema_description.append(f - 字段 {field_name}: 类型为 {field_type}, { if is_null YES else 非空}, {f主键 if key_type PRI else }) schema_description.append() # 表之间空一行 cursor.close() connection.close() except Exception as e: return f获取数据库结构时出错: {e} return \n.join(schema_description) # 数据库配置 db_config { host: localhost, user: root, # 你的数据库用户名 password: your_password, # 你的数据库密码 database: company_sales, # 你的数据库名 charset: utf8mb4 } # 打印出Schema看看效果 schema_text get_database_schema(db_config) print(数据库结构描述) print(schema_text)运行这段代码你会得到一个清晰的文本描述列出了数据库里所有表和它们的字段。这就是我们要喂给模型的“地图”。4.2 第二步设计“工作说明书”Prompt工程这是最关键的一步。Prompt的质量直接决定了模型生成SQL的准确率。我们的Prompt需要包含以下几个部分系统角色设定告诉模型它现在是一个专业的SQL专家。任务指令清晰说明它需要做什么。数据库结构把上一步获取的Schema放进来。输出格式要求严格要求它只输出SQL代码不要有任何多余的解释。用户问题最终用户提出的自然语言查询。def build_sql_generation_prompt(user_query: str, db_schema: str) - str: 构建用于生成SQL的Prompt。 prompt f你是一个资深的MySQL数据库专家。你的任务是根据下面的数据库表结构将用户的自然语言问题转换成一条准确、可执行的MySQL查询语句。 数据库表结构如下 {db_schema} 请严格遵守以下规则 1. 只生成一条SQL语句不要生成多条。 2. 语句必须符合MySQL语法。 3. 只能进行SELECT查询操作严禁生成INSERT、UPDATE、DELETE、DROP等任何会修改数据或结构的语句。 4. 输出的结果必须只是纯SQL代码不要包含任何额外的解释、说明或Markdown代码块标记。 用户的问题是“{user_query}” 请直接输出对应的SQL语句 return prompt这个Prompt明确了角色、任务、规则和格式能极大地提高模型输出的准确性和安全性。4.3 第三步调用模型API获取SQL现在我们可以将组装好的Prompt发送给通义千问WebUI的API。import requests import json def generate_sql_via_api(user_query: str, db_schema: str, api_url: str) - str: 调用通义千问WebUI API将自然语言问题转换为SQL。 prompt build_sql_generation_prompt(user_query, db_schema) # 假设WebUI API兼容OpenAI格式 payload { model: qwen1.5-1.8b-chat-gptq-int4, # 根据实际部署的模型名调整 messages: [ {role: user, content: prompt} ], max_tokens: 500, temperature: 0.1, # 温度调低使输出更确定、更稳定 stream: False } headers { Content-Type: application/json } try: response requests.post(api_url, headersheaders, datajson.dumps(payload), timeout30) response.raise_for_status() result response.json() # 解析返回内容获取模型生成的文本 generated_sql result[choices][0][message][content].strip() return generated_sql except requests.exceptions.RequestException as e: return fAPI调用失败: {e} except (KeyError, json.JSONDecodeError) as e: return f解析API响应失败: {e}4.4 第四步给SQL加上“安全锁”校验与过滤绝对不能直接执行模型生成的SQL我们必须先进行安全检查。import re def validate_and_sanitize_sql(sql: str) - tuple[bool, str]: 校验和清洗SQL语句。 返回 (是否安全, 清洗后的SQL或错误信息) # 1. 转换为小写便于检查 sql_lower sql.lower().strip() # 2. 安全过滤禁止任何非SELECT的操作 dangerous_keywords [insert, update, delete, drop, truncate, alter, create, grant, revoke] for keyword in dangerous_keywords: # 使用正则确保是独立的SQL关键字避免误伤字段名 if re.search(rf\b{keyword}\b, sql_lower): return False, f安全检查失败生成的SQL包含危险操作 {keyword.upper()}已阻止执行。 # 3. 基本语法校验确保以select开头 if not sql_lower.startswith(select): return False, fSQL语法校验失败语句不是以SELECT开头。生成的SQL是{sql} # 4. 可选更复杂的语法校验可以使用第三方库如sqlparse # import sqlparse # try: # parsed sqlparse.parse(sql) # # 进行更细致的分析... # except Exception as e: # return False, fSQL解析失败: {e} # 5. 返回清洗后的SQL这里可以做一些简单的格式化但非必须 safe_sql sql.strip().rstrip(;) ; # 确保以分号结尾 return True, safe_sql4.5 第五步执行查询并返回结果最后将安全的SQL语句送到MySQL中执行并将结果返回。def execute_safe_query(sql: str, db_config: dict) - tuple[bool, str]: 执行安全的SQL查询语句并返回结果。 try: connection pymysql.connect(**db_config) cursor connection.cursor(pymysql.cursors.DictCursor) # 返回字典格式更易读 cursor.execute(sql) results cursor.fetchall() cursor.close() connection.close() # 将结果格式化为字符串 if not results: return True, 查询成功但未找到匹配的数据。 # 简单表格化输出 output_lines [] headers results[0].keys() output_lines.append( | .join(headers)) output_lines.append(- * (len( | .join(headers)))) for row in results: output_lines.append( | .join(str(row[h]) for h in headers)) return True, \n.join(output_lines) except pymysql.Error as e: return False, f数据库执行错误: {e}5. 实战演练组装完整的查询流程让我们把上面的所有步骤串起来形成一个完整的处理流程。def natural_language_to_query(user_question: str) - str: 主函数接收用户自然语言问题返回查询结果。 print(f用户问题: {user_question}) # 1. 获取数据库Schema print(正在获取数据库结构...) schema get_database_schema(db_config) # 2. 调用模型生成SQL print(正在请求AI模型生成SQL...) api_endpoint http://localhost:8000/v1/chat/completions # 替换为你的API地址 raw_sql generate_sql_via_api(user_question, schema, api_endpoint) print(f模型原始返回: {raw_sql}) # 3. 校验和清洗SQL print(正在进行SQL安全检查...) is_safe, processed_sql validate_and_sanitize_sql(raw_sql) if not is_safe: return f【安全拦截】{processed_sql} print(f安全SQL: {processed_sql}) # 4. 执行查询 print(正在执行查询...) success, result execute_safe_query(processed_sql, db_config) if not success: return f【查询失败】{result} # 5. 返回最终结果 return f查询成功\n\n执行语句\n{processed_sql}\n\n查询结果\n{result} # 测试几个例子 if __name__ __main__: test_questions [ 上个月销售额最高的前五个产品是什么, 电子产品类别的总销售额是多少, 列出所有单价超过1000元的产品名称和销量。, ] for q in test_questions: print(\n *50) answer natural_language_to_query(q) print(answer) print(*50)运行这个脚本你会看到系统如何一步步将“上个月销售额最高的前五个产品是什么”这样的中文问题转换成类似SELECT product_name, SUM(sales_amount) AS total_sales FROM product_sales WHERE sale_date 2024-04-01 AND sale_date 2024-05-01 GROUP BY product_name ORDER BY total_sales DESC LIMIT 5;的SQL语句并返回查询结果。6. 总结与展望通过上面的实战我们成功搭建了一个原型系统它像一位随时在线的“数据翻译官”将业务人员的自然语言问题精准地翻译成数据库能听懂的SQL命令。整个流程的核心在于Prompt设计和安全兜底。一个好的Prompt能引导模型充分利用我们提供的Schema信息而严格的安全校验则是系统上线前必须筑牢的防线。实际应用中这个系统还有很多可以优化和扩展的地方。例如可以增加对查询结果的可视化自动生成简单图表可以缓存常见的查询模式以提升响应速度或者引入更复杂的对话上下文管理让用户能进行多轮追问比如“那它们的平均单价呢”。这种自然语言查询数据库的能力特别适合嵌入到企业内部的数据门户、报表平台或聊天机器人中。它极大地降低了数据获取的门槛让每个员工都能成为“数据驱动决策”的参与者而不仅仅是技术部门的专属能力。从“人适应工具”到“工具理解人”这或许就是技术带来的最直观的效率提升。获取更多AI镜像想探索更多AI镜像和应用场景访问 CSDN星图镜像广场提供丰富的预置镜像覆盖大模型推理、图像生成、视频生成、模型微调等多个领域支持一键部署。