ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

InnoAI SQL 助手|用自然语言,重塑数据库交互

InnoAI SQL 助手|用自然语言,重塑数据库交互 1.项目说明本项目以 MySQL 8.0 DBA 运维核心知识点为基础结合硅基流动开源大模型 API构建一套电商订单库智能查询与性能调优系统。系统可接收业务自然语言自动生成合规 MySQL 查询语句自动执行查询并输出结构化表格依托大模型完成订单数据业务解读同时解析 SQL 执行计划输出标准化索引优化方案全程无需人工手写、分析 SQL。核心价值无需专业 SQL 开发能力即可完成业务数据查询自动替代人工统计报表、手工分析执行计划等重复性运维工作深度融合 MySQL 数据库运维能力与大模型自然语言解析能力适配企业轻量化数据查询、SQL 性能优化、AI 智能解读一体化落地场景。2.项目介绍2.1功能需求① 支持自然语言转MySQL 只读查询语句仅生成 SELECT拦截所有增删改 DDL/DML 语句② 自动执行生成 SQL格式化输出表格化查询结果调用大模型输出通俗易懂业务总结③ 输入任意业务 SQL自动解析 EXPLAIN 执行计划输出分级性能问题、可直接执行索引、改写方案④ 配置独立环境文件存储数据库账号、大模型密钥避免代码硬编码保障敏感信息安全2.2非功能需求① 兼容性适配 openEuler/RHEL Linux 系统兼容 MySQL 8.0.45适配Qwen、DeepSeek 系列开源模型② 稳定性自然语言识别容错率高无匹配数据可正常提示API、数据库异常捕获不崩溃③ 安全性仅开放只读查询权限密钥文件设置 600 权限不打印明文账号密钥2.3技术架构2.3.1流程图2.3.2架构说明一、左侧交互层面向运维、开发、运营人员双使用场景 命令行终端部署在 openEuler 服务器运行python3 main.py唤起交互菜单依靠自然语言完成数据查询、SQL 性能调优。 Web 可视化端基于 Streamlit 搭建网页面板浏览器即可访问具备输入校验、表格展示、代码复制等功能可视化完成查询与 SQL 优化。二、Python 核心程序层分层解耦架构方便教学与二次开发 main.py项目总调度封装自然语言转 SQL、数据总结、SQL 调优核心逻辑为命令行、Web 端提供共用方法。 web_main.py网页界面层负责页面布局、输入校验、结果渲染、代码复制功能。 prompts.py提示词管理层统一存放 NL2SQL、SQL 优化提示模板分离提示词与业务逻辑。 mysql_client.py数据库访问层封装 MySQL 连接操作增加安全校验仅放行 SELECT 查询语句规避删改数据风险。 .env 配置文件单独存放数据库参数、大模型密钥等敏感配置实现配置与代码分离。三、底层数据持久层搭载 openEuler 虚拟机内的 MySQL 8.0.45 数据库以电商订单表testdb.order_info作为测试数据源支撑查询与 SQL 优化测试。四、AI 大模型服务层接入腾讯云 TokenHub 大模型聚合平台为 SQL 生成、数据分析、语句调优提供 AI 能力。 兼容 OpenAI 接口格式可快速替换 DeepSeek、通义千问等主流模型统一完成鉴权、计费与运维依托云服务保障稳定性可适配生产环境。3.软硬件环境清单4. 任务清单4.1. 项目环境搭建部署 openEuler 服务器关闭 SELinux、配置可用 yum 源编译安装 Python3.11.9 安装 MySQL8.0.45创建 testdb 库、order_info 订单业务表导入20 条标准测试订单数据 登录并开通腾讯云 TokenHub 大模型聚合平台申请 API 密钥领取免费额度编写.env 配置文件并加固 文件权限 安装项目全部 Python 依赖包测试数据库连通性、大模型接口连通性。4.2. 脚本开发 mysql_client.py封装 MySQL 连接、查询与执行计划获取拦截危险 SQL 保障数据库安全。 prompts.py统一存放生成 SQL、调优分析两套 AI 提示词并提供提取纯净 SQL 的工具函数。 main.py项目总调度串联数据库、大模型、提示词提供终端菜单交互实现完整业务逻辑。 web_main.pyStreamlit 可视化网页界面做输入校验、图形化展示结果复用 main 核心逻辑。 .env存放数据库、腾讯云 TokenHub 大模型密钥等配置分离敏感信息与业务代码。4.3. 功能测试多业务自然语言用例全覆盖测试校验生成 SQL 安全、逻辑准确模糊匹配无 bug 性能调优模块测试校验 EXPLAIN 解析完整、输出索引与改写方案可直接执行 边界场景测试无匹配用户 / 商品、空白输入、超长复合需求程序无崩溃报错 安全测试验证不会生成任何 DELETE/UPDATE/ALTER 等危险 SQL密钥无明文打印5.项目部署5.1环境搭建5.1.1系统搭建及初始化配置实验需安装1台虚拟机及OpenEuler2203_SP4系统关闭selinx更换时间同步服务器下载所需软件及依赖5.1.2源码编译安装Python3.11.9下载https://www.python.org/downloads/release/python-3119/下载完毕后使用XFTP将源码包上传到/usr/local/src路径下[rootyaoguoqiang ~]# cd /usr/local/src # 解压 [rootyaoguoqiang src]# tar -zxvf Python-3.11.9.tgz [rootyaoguoqiang src]# cd Python-3.11.9 # 编译配置 [rootyaoguoqiang Python-3.11.9]# ./configure --prefix/usr/local/python3.11 --enable-shared # 多核编译安装 [rootyaoguoqiang Python-3.11.9]# make -j$(nproc) make install # 配置动态链接库解决libpython缺失报错 [rootyaoguoqiang Python-3.11.9]# echo /usr/local/python3.11/lib /etc/ld.so.conf.d/python311.conf [rootyaoguoqiang Python-3.11.9]# ldconfig # 建立全局软链接不覆盖系统自带Python3 [rootyaoguoqiang Python-3.11.9]# ln -s /usr/local/python3.11/bin/python3.11 /usr/local/bin/python3 [rootyaoguoqiang Python-3.11.9]# bash # 或者reboot重启 # 验证安装 [rootyaoguoqiang Python-3.11.9]# python3 -V [rootyaoguoqiang Python-3.11.9]# ln -s /usr/local/python3.11/bin/pip3.11 /usr/local/bin/pip3 [rootyaoguoqiang Python-3.11.9]# pip3 -V # 校验SSL模块AI接口必备 [rootyaoguoqiang Python-3.11.9]# python3 -c import ssl; print(ssl.OPENSSL_VERSION)5.1.3配置国内 pip 源及安装项目依赖配置pip仓库为阿里镜像站可提高下载速度[rootyaoguoqiang Python-3.11.9]# cd [rootyaoguoqiang ~]# mkdir .pip [rootyaoguoqiang ~]# cat ~/.pip/pip.conf EOF [global] index-url http://mirrors.aliyun.com/pypi/simple/ [install] trusted-hostmirrors.aliyun.com安装python及ai所需依赖[rootyaoguoqiang ~]# pip3 install --upgrade pip [rootyaoguoqiang ~]# pip3 install pymysql python-dotenv tabulate langchain langchain-openai5.1.4. 部署并初始化MySQL 8.0.45下载https://downloads.mysql.com/archives/community/使用xftp将软件包上传到根目录部署数据库# 解压缩 [rootyaoguoqiang /]# tar -xvf mysql-8.0.45-linux-glibc2.28-x86_64.tar.xz [rootyaoguoqiang /]# cd mysql-8.0.45-linux-glibc2.28-x86_64 [rootyaoguoqiang mysql-8.0.45-linux-glibc2.28-x86_64]# ls bin docs include lib LICENSE man README share support-files # 使用前的准备 [rootyaoguoqiang mysql-8.0.45-linux-glibc2.28-x86_64] cd / [rootyaoguoqiang /]# mv mysql-8.0.45-linux-glibc2.28-x86_64 /usr/local/mysql [rootyaoguoqiang /]# cd /usr/local/mysql [rootyaoguoqiang mysql]# groupadd mysql # 创建名为mysql的用户组 # 创建mysql的系统用户将其添加到mysql组中并设置其不可登录以限制该用户的登录权限 [rootyaoguoqiang mysql]# useradd -r -g mysql -s /sbin/nologin mysql [rootyaoguoqiang mysql]# mkdir data # 创建用于存放MySQL数据文件目录 [rootyaoguoqiang mysql]# chmod -R 750 data # 设置mysql目录的账户及工作组生产环境中不要使用root [rootyaoguoqiang mysql]# chown -R mysql:mysql /usr/local/mysql # 初始化软件 [rootyaoguoqiang mysql]# bin/mysqld --initialize --usermysql --basedir/usr/local/mysql --datadir/usr/local/mysql/data # 注意需要复制密码 [rootyaoguoqiang mysql]# bin/mysqld_safe --usermysql # 使用后台方式以mysql用户身份启动 MySQL 服务器mysqld_safe 是一个用于启动和监控 MySQL 服务器的脚本 # 注意此时上述命令执行完毕处于后台运行状态需要另行启动一个终端 [rootyaoguoqiang ~]# ps -ef | grep mysql # 查看进程运行状态 [rootyaoguoqiang ~]# cd /usr/local/mysql [rootyaoguoqiang mysql]# bin/mysql -u root -p # 登录可能报错 # 可选若报错需要找到下面的文件进行软连接 [rootyaoguoqiang mysql]# ln -s /usr/lib64/libncurses.so.6.3 /usr/lib64/libncurses.so.5 [rootyaoguoqiang mysql]# ln -s /usr/lib64/libtinfo.so.6.3 /usr/lib64/libtinfo.so.5 [rootyaoguoqiang mysql]# bin/mysql -u root -p Enter password: # 粘贴之前的初始密码 # 以上可选 mysql alter user rootlocalhost identified with mysql_native_password by 123456; # 修改密码 mysql flush privileges; # 刷新 mysql use mysql; # 查看账户信息 mysql select user, host, plugin from mysql.user; ---------------------------------------------------- | user | host | plugin | ---------------------------------------------------- | mysql.infoschema | localhost | caching_sha2_password | | mysql.session | localhost | caching_sha2_password | | mysql.sys | root | localhost | caching_sha2_password | | localhost | mysql_native_password | ---------------------------------------------------- 4 rows in set (0.00 sec) mysqlexit [rootyaoguoqiang mysql]# ps -ef | grep mysql [rootyaoguoqiang mysql]# kill -9 pid号 # 在当前终端关闭运行的mysql # 设置mysql的配置文件 # 回到之前的终端敲一个回车显示进程以杀死 [rootyaoguoqiang mysql]# vim /etc/my.cnf # 新建配置文件输入以下内容 [client] port 3306 socket /tmp/mysql.sock [mysqld] port 3306 basedir /usr/local/mysql datadir /usr/local/mysql/data tmpdir /tmp socket /tmp/mysql.sock character-set-server utf8mb4 collation-server utf8mb4_general_ci default-storage-engineINNODB log_error error.log # 配置启动脚本 [rootyaoguoqiang mysql]# vim /usr/lib/systemd/system/mysqld.service [Unit] DescriptionMySQL Server Afternetwork.target remote-fs.target nss-lookup.target [Service] Typenotify Usermysql Groupmysql ExecStart/usr/local/mysql/bin/mysqld --defaults-file/etc/my.cnf LimitNOFILE65535 LimitNPROC65535 Restarton-failure RestartPreventExitStatus1 TimeoutSec0 [Install] WantedBymulti-user.target [rootyaoguoqiang mysql]# systemctl daemon-reload [rootyaoguoqiang mysql]# systemctl enable --now mysqld.service # 设置mysql命令识别 [rootyaoguoqiang mysql]# vim ~/.bash_profile # 设置环境变量需添加如下语句 export PATH$PATH:/usr/local/mysql/bin [rootyaoguoqiang mysql]# source ~/.bash_profile # 测试 [rootyaoguoqiang mysql]# mysql -V mysql Ver 8.0.45 for Linux on x86_64 (MySQL Community Server - GPL) [rootyaoguoqiang mysql]# systemctl is-active mysqld active [rootyaoguoqiang ~]# mysql -uroot -p Enter password: mysql show databases; -------------------- | Database | -------------------- | information_schema | | mysql | | performance_schema | | sys # 123456 | -------------------- 4 rows in set (0.01 sec)创建表和库5.2. 获取API Key访问腾讯云官网手机号注册并完成实名认证登录后进入 “API Key管理”→“新建 API 密钥”填写密钥名称并保存5.3脚本开发5.3.1. 新建目录及脚本5.3.2. 编写环境变量脚本5.3.3. 编写数据库连接脚本vim /opt/mysql_ai_tools/mysql_client.py5.3.4. 编写sql转换脚本[rootyaoguoqiang ~]# vim /opt/mysql_ai_tools/prompts.py5.3.5. 编写程序入口脚本vim /opt/mysql_ai_tools/main.py# -*- coding: utf-8 -* # 文件名main.py # 功能项目核心业务逻辑 终端交互式菜单入口 # 作用统一封装大模型调用、SQL清洗、数据库交互两大核心业务命令行/网页共用底层函数 import os import re import logging from dotenv import load_dotenv # 兼容OpenAI标准大模型接口适配腾讯云TokenHub from langchain_openai import ChatOpenAI # 导入数据库操作封装类 from mysql_client import Mysql80Client # 表格格式化打印工具美化终端输出查询结果 from tabulate import tabulate # 导入提示词管理类与全局实例 from prompts import UnifiedPrompt, prompt_helper # 全局日志配置替代print记录运行时间、日志级别、报错信息方便排障 logging.basicConfig(levellogging.INFO, format%(asctime)s - %(levelname)s - % (message)s) logger logging.getLogger(__name__) def check_config() - None: 程序启动前置配置校验函数 作用提前检测.env必填参数是否存在避免运行中途缺参数崩溃 # 大模型必填参数列表 required_llm [LLM_API_KEY, LLM_BASE_URL, LLM_MODEL_NAME] missing [k for k in required_llm if not os.getenv(k)] if missing: raise ValueError(f配置缺失请在 .env 文件中填写 {, .join(missing)}) # 数据库必填参数列表 required_db [MYSQL_HOST, MYSQL_USER, MYSQL_DB] missing_db [k for k in required_db if not os.getenv(k)] if missing_db: raise ValueError(f数据库配置缺失请检查 {, .join(missing_db)}) def get_llm() - ChatOpenAI: 初始化大模型客户端 适配腾讯云TokenHub等全部兼容OpenAI接口规范的MaaS平台 返回可直接调用的大模型实例 # 从环境变量读取大模型连接信息 api_key os.getenv(LLM_API_KEY) base_url os.getenv(LLM_BASE_URL) model_name os.getenv(LLM_MODEL_NAME) # 温度不存在则默认0.1数值越低输出越严谨稳定 temperature float(os.getenv(LLM_TEMPERATURE, 0.1)) return ChatOpenAI( api_keyapi_key, base_urlbase_url, modelmodel_name, temperaturetemperature ) def clean_sql_spacing(sql: str) - str: SQL标准化清洗工具函数兜底修复各大模型输出格式 解决中文空格别名、中文标点、特殊空白、关键字连写等语法报错问题 入参大模型原始SQL字符串 返回清洗后可直接执行的标准英文SQL if not sql: return # 1. 统一替换各类中文全角空格、换行、制表符为普通半角空格 special_spaces [ \xa0, \u200b, \u200c, \u200d, \u200e, \u200f, \u3000, \t, \n, \r ] for sp in special_spaces: sql sql.replace(sp, ) # 2. 删除不可见控制字符防止解析异常 sql re.sub(r[\x00-\x1f\x7f], , sql) # 3. 中文标点批量替换为英文标点解决Qwen等模型输出中文逗号报错 sql sql.replace(, ,).replace(, ;).replace(, ().replace(, )) # 4. 多个连续空格合并为单个去除首尾多余空格 sql re.sub(r\s, , sql).strip() # 5. 精准处理AS别名内部空格只删别名里空格保留AS与别名之间分隔空格 def _clean_alias_space(match): prefix match.group(1) # 捕获AS关键字 alias match.group(2) # 捕获后面全部别名文本 alias_clean re.sub(r\s, , alias) return f{prefix} {alias_clean} # 匹配AS后别名截止逗号、FROM、WHERE等关键字前停止匹配 sql re.sub( r\b(AS)\s(.?)(? \s*,\s*|\sFROM\b|\sWHERE\b|\sORDER\b|\sGROUP\b|\sLIMIT\b|\s*;), _clean_alias_space, sql, flagsre.IGNORECASE ) # 6. 自动给连写的关键字补空格字段/中文关键字粘连自动拆分 keywords_upper [ SELECT, FROM, WHERE, ORDER BY, GROUP BY, AND, OR, LIMIT, DESC, ASC, AS, INNER JOIN, LEFT JOIN, RIGHT JOIN, ON, INSERT INTO, UPDATE, SET, DELETE FROM, VALUES, LIKE, IN, BETWEEN, IS NULL, COUNT, SUM, AVG, MAX, MIN, OVER ] for kw in keywords_upper: # 字母下划线关键字粘连拆分补充第三个参数sql pattern r([a-z_])( re.escape(kw) r) sql re.sub(pattern, r\1 \2, sql) # 中文文字关键字粘连拆分补充第三个参数sql pattern_cn r([\u4e00-\u9fa5])( re.escape(kw) r) sql re.sub(pattern_cn, r\1 \2, sql) # 7. 统一所有SQL关键字大写格式标准化 keywords_lower [kw.lower() for kw in keywords_upper] for kw in keywords_lower: sql re.sub( r\b re.escape(kw) r\b, kw.upper(), sql, flagsre.IGNORECASE ) # 最终再清理一遍多余空格 sql re.sub(r\s, , sql).strip() return sql def nl2sql_query(user_input: str) - dict: 核心业务1自然语言转SQL、执行查询、AI生成业务总结 对外统一标准返回字典终端/网页程序均可直接调用无重复代码 入参用户自然语言查询需求 返回包含执行状态、SQL、字段、数据、AI总结、模型原始输出 # 初始化大模型、数据库客户端 llm get_llm() db Mysql80Client() try: logger.info(正在生成SQL语句...) # 1. 加载NL2SQL提示词填充用户需求传给大模型 prompt UnifiedPrompt.NL_TO_SQL_PROMPT.format(user_inputuser_input) response llm.invoke(prompt) raw_content response.content.strip() # 2. 从模型返回文本提取纯净SQL提取失败直接抛异常 extracted_sql prompt_helper.extract_sql(raw_content) if not extracted_sql: raise Exception(大模型未返回有效SQL请重新描述需求) # 3. 清洗SQL修复各类格式问题 clean_sql clean_sql_spacing(extracted_sql) logger.info(f生成SQL{clean_sql}) # 4. 数据库执行查询拿到表头与数据 columns, rows db.execute_query(clean_sql) # 5. 如果有数据调用大模型生成业务解读总结 summary if rows: logger.info(正在生成数据总结...) summary_prompt f 以下是真实的SQL查询结果请作为电商数据分析师给出简练的业务总结。 SQL语句{clean_sql} 查询数据{str(rows)} 重点说明数据反映的业务含义如有异常值请指出。 summary_resp llm.invoke(summary_prompt) summary summary_resp.content.strip() # 成功结果返回 return { success: True, sql: clean_sql, columns: columns, rows: rows, summary: summary, raw_llm: raw_content } except Exception as e: # 捕获全流程所有异常记录日志并返回错误信息 logger.error(f查询处理失败{str(e)}) return { success: False, error: str(e), raw_llm: raw_content if raw_content in dir() else } finally: # 无论成功失败都关闭数据库连接释放资源 db.close() def sql_tune_analyze(raw_sql: str) - dict: 核心业务2SQL性能调优分析 流程清洗SQL → 获取EXPLAIN执行计划 → AI分析给出优化方案 入参用户输入待优化SQL 返回执行状态、清洗后SQL、执行计划字段/内容、调优建议 llm get_llm() db Mysql80Client() try: # 先标准化清洗SQL clean_sql clean_sql_spacing(raw_sql) logger.info(正在获取执行计划...) # 调用数据库封装方法获取EXPLAIN执行计划 columns, plan_rows db.get_explain_plan(clean_sql) # 填充调优提示词传入SQL和执行计划让AI分析瓶颈 logger.info(正在分析性能瓶颈...) prompt UnifiedPrompt.SQL_TUNE_PROMPT.format( sql_inputclean_sql, explain_datastr(plan_rows) ) response llm.invoke(prompt) return { success: True, sql: clean_sql, plan_columns: columns, plan_rows: plan_rows, suggestion: response.content.strip() } except Exception as e: logger.error(f调优分析失败{str(e)}) return { success: False, error: str(e) } finally: # 操作结束关闭数据库连接 db.close() def main_cli(): 终端交互入口主函数 提供循环菜单支持用户选择查询/调优/退出纯终端操作 # 程序启动先校验全部配置失败直接退出菜单 try: check_config() except ValueError as e: print(f ❌ {e}) return # 循环交互不退出可持续多次使用 while True: print(\n InnoAI SQL 助手 ) print(1. 自然语言生成SQL自动查询并AI总结数据) print(2. 输入SQL语句AI分析执行计划并给出调优方案) print(0. 退出程序) choice input(请输入功能序号: ).strip() # 功能1自然语言查数据 if choice 1: query input(请输入你的数据查询需求: ).strip() if not query: print( ⚠ 请输入有效需求) continue result nl2sql_query(query) # 处理失败场景打印错误与模型原始输出 if not result[success]: print(f\n ❌ 处理失败{result[error]}) if result.get(raw_llm): print(f大模型原始回复\n{result[raw_llm]}) continue # 成功打印SQL、格式化表格展示数据、输出业务总结 print(f\n ✅ 生成SQL) print(result[sql]) if result[rows]: print(f\n 查询结果共 {len(result[rows])} 条) print(tabulate(result[rows], headerskeys, tablefmtpretty)) if result[summary]: print(f\n 业务总结\n{result[summary]}) else: print(\n ⚠ 未查询到匹配数据) # 功能2SQL性能调优 elif choice 2: sql_input input(\n请输入需要分析的 SQL 语句: ).strip() if not sql_input: print( ⚠ 请输入有效SQL) continue result sql_tune_analyze(sql_input) if not result[success]: print(f\n ❌ 分析失败{result[error]}) continue # 打印执行计划表格和AI优化建议 print(f\n 执行计划详情) print(tabulate(result[plan_rows], headerskeys, tablefmtpretty)) print(f\n 调优建议\n{result[suggestion]}) # 0 退出循环结束程序 elif choice 0: print(程序已安全退出。) break # 无效数字输入提示 else: print(无效输入请重试。) print(\n - * 40) # 程序入口直接运行main.py则启动终端菜单 if __name__ __main__: main_cli()6. 测试 InnoAI SQL 助手 1. 自然语言生成SQL自动查询并AI总结数据 2. 输入SQL语句AI分析执行计划并给出调优方案 0. 退出程序 请输入功能序号: 2 请输入需要分析的 SQL 语句: SELECT user_id AS 用户ID, SUM(pay_amount) AS 总消费金额, COUNT(id) AS 订单笔数 FROM order_info WHERE user_id IN (1001, 1002, 1003) GROUP BY user_idORDER BY 总消费金额 DESC 2026-06-26 21:45:20,446 - INFO - 正在获取执行计划... 2026-06-26 21:45:20,448 - INFO - 正在分析性能瓶颈... 2026-06-26 21:46:36,124 - INFO - HTTP Request: POST https://tokenhub.tencentmaas.com/v1/chat/completions HTTP/1.1 200 OK 执行计划详情 ----------------------------------------------------------------------------------------------------------------------------------------------- | id | select_type | table ref | rows | filtered | 调优建议 1. **核心性能问题** | partitions | type | possible_keys | key | key_len | Extra | ----------------------------------------------------------------------------------------------------------------------------------------------- | 1 | SIMPLE | order_info | | ALL | | | | | 20 | 30.0 | Using where; Using temporary; Using filesort | ------------------------------------------------------------------------------------------------------------------------------------------------ **全表扫描 (type: ALL)**user_id 字段无索引导致查询扫描全表数据量大时性能急剧下降。- **临时表与文件排序**Extra 显示 Using temporary; Using filesort说明分组和排序未在索 引上完成消耗额外内存和 CPU。- **无索引命中**key 为 None查询未利用任何索引加速过滤和分组。 2. **建索引 SQL**- 创建覆盖索引加速 WHERE 过滤、GROUP BY 分组并避免回表查询 pay_amount。 sql ALTER TABLE order_info ADD INDEX idx_user_id_pay_amount (user_id, pay_amount); ​7. web可视化版本7.1. Streamlit介绍Streamlit 是开源、纯 Python Web 开发库核心定位不用写 HTML/CSS/JS只用 Python 就能快速做交互式网页专门面向数据分析师、后端、AI 工程师把本地脚本一键变成可视化 Web 面板。1.特点协议MIT 开源商用免费运行原理执行 Python 脚本自动转网页 UI用户操作时整段脚本从上到下重新运行刷新页面最贴合当前场景把原本命令行 Shell MySQL-AI 工具低成本改成浏览器可视化界面组件开箱即用内置全套交互控件开发热重载改代码自动刷新页面部署极其简单支持服务器system常驻无缝兼容 Python 全生态2.局限性并发性能一般单进程模型自定义 UI 能力弱原生无登录权限控制7.2. 部署流程7.2.1. 原则已有业务文件 main.py mysql_client.py prompts.py .env文件不变需要编写web_main.py入口文件即可7.2.2. 安装 Python 依赖7.2.3. 创建 Streamlit 可视化入口 web_main.pyvim /opt/mysql_ai_tools/web_main.py# -*- coding: utf-8 -* # 文件名web_main.py # 功能Streamlit网页可视化界面 # 说明前端交互页面完全复用main.py封装好的业务函数无需重复编写AI、数据库逻辑 # 两大页面自然语言查数据、SQL性能调优做输入前置校验、美化结果展示 import streamlit as st import os import re # 从核心主程序导入通用业务函数、配置校验方法 from main import check_config, nl2sql_query, sql_tune_analyze # 全局页面基础配置页面标题、页面宽度铺满屏幕 st.set_page_config(page_titleInnoAI SQL 助手, layoutwide) # 全局CSS样式定制优化字体、间距、按钮、代码块、表格展示 # 使用markdown注入前端样式统一页面视觉效果方便演示观看 st.markdown( style /* 全局文字基础样式统一字体、字号、行间距适配Windows/Mac中文显示 */ html, body, [class*css] { font-size: 15px; line-height: 1.6; font-family: -apple-system, BlinkMacSystemFont, Segoe UI, PingFang SC, Microsoft YaHei, sans-serif; } /* 页面主体容器左右留白收窄太宽的数据表格阅读疲劳 */ .block-container { padding-top: 2.5rem; padding-bottom: 3rem; max-width: 1100px; margin: 0 auto; } /* 各级标题字号、粗细、边距统一优化 */ h1 { font-size: 2rem !important; font-weight: 600; margin-bottom: 1.8rem; letter-spacing: 0.5px; } h2, h3 { font-weight: 600; margin-top: 1.5rem; margin-bottom: 1rem; } h3 { font-size: 1.25rem !important; } /* 文本输入框标签样式美化 */ .stTextArea label p { font-size: 15px; font-weight: 500; color: #1f2937; margin-bottom: 0.5rem; } /* 输入框内部样式字号、圆角、内边距 */ textarea { font-size: 15px !important; line-height: 1.6 !important; border-radius: 8px !important; padding: 12px 14px !important; } /* 全局操作按钮统一尺寸、圆角、内边距视觉统一 */ .stButton button { font-size: 15px !important; font-weight: 500; padding: 0.65rem 2.2rem !important; border-radius: 8px !important; min-width: 160px; } /* 左侧侧边栏样式调整 */ section[data-testidstSidebar] { font-size: 14.5px; } /* 侧边大标题禁止自动换行 */ section[data-testidstSidebar] h1 { font-size: 1.5rem !important; white-space: nowrap; margin-bottom: 1.2rem; } /* 侧边单选按钮间距放大 */ section[data-testidstSidebar] .stRadio div { gap: 0.8rem; } /* 提示警告框字号统一 */ .stAlert { font-size: 14.5px; border-radius: 8px !important; } /* 重点修复代码块复制按钮失效问题 */ .stCodeBlock { position: relative !important; border-radius: 8px !important; } /* 强制显示复制按钮提高层级防止被遮挡 */ .stCodeBlock button { opacity: 1 !important; visibility: visible !important; pointer-events: auto !important; z-index: 999 !important; width: 36px; height: 36px; top: 10px; right: 10px; border-radius: 6px; background: #f3f4f6 !important; color: #374151 !important; border: 1px solid #e5e7eb !important; } /* 按钮悬浮变色提升交互感 */ .stCodeBlock button:hover { background: #e5e7eb !important; } /* SQL代码等宽字体优化提升代码可读性 */ .stCodeBlock code, .stCodeBlock pre { font-size: 14.5px !important; line-height: 1.7 !important; font-family: JetBrains Mono, Consolas, Monaco, monospace; } /* 数据表格单元格内边距放大避免文字拥挤 */ .stDataFrame { font-size: 14.5px; border-radius: 8px; overflow: hidden; } .stDataFrame [data-testidtable] td { padding: 10px 12px; } /style , unsafe_allow_htmlTrue) # 全局一次性配置校验会话缓存避免重复校验 # st.session_statestreamlit会话全局存储页面刷新前一直生效 if config_checked not in st.session_state: try: # 调用main.py的配置校验函数检测.env文件必填参数 check_config() # 标记已校验下次页面刷新不再重复执行 st.session_state.config_checked True except ValueError as e: # 配置缺失直接弹窗报错终止页面加载 st.error(f配置错误{e}) st.stop() # 左侧侧边栏区域系统标题、当前模型展示、页面切换导航 with st.sidebar: st.title( InnoAI SQL 助手) # 读取环境变量展示当前正在使用的大模型名称 st.info(f当前模型{os.getenv(LLM_MODEL_NAME, 未知)}) # 单选框切换两大功能页面 page st.radio(功能导航, [ 数据查询与总结, ⚙ SQL 性能调优]) # 页面1自然语言转SQL查询页面 if page 数据查询与总结: st.header( 自然语言转 SQL 查询) # 多行文本输入框接收用户中文业务需求 user_input st.text_area(请输入你的业务查询需求, height150) # 点击提交按钮触发查询逻辑 if st.button( 生成并执行, typeprimary): input_trim user_input.strip() # 校验1输入为空拦截 if not input_trim: st.warning(请输入有效的业务查询需求后再提交) # 校验2禁止直接粘贴SQL区分两个页面的使用场景 elif re.match(r(?i)^\s*SELECT\s, input_trim): st.warning(此处请输入自然语言描述的查询需求例如查询用户 1001 的所有订单请勿直接 粘贴 SQL 语句。) # 输入校验全部通过执行AI查询逻辑 else: # 加载动画提示用户等待 with st.spinner(AI 正在生成 SQL 并查询数据...): # 调用main封装好的核心业务方法 result nl2sql_query(user_input) # 分支1业务执行失败展示错误信息 if not result[success]: st.error(f处理失败{result[error]}) # 折叠面板展示大模型原始返回内容方便排错 if result.get(raw_llm): with st.expander(查看大模型原始回复): st.code(result[raw_llm]) # 分支2执行成功分层展示结果 else: st.success(SQL 生成并执行成功) # 高亮展示生成后的标准SQL语句 st.code(result[sql], languagesql) # 存在查询数据则渲染表格 if result[rows]: st.dataframe(result[rows], use_container_widthTrue) # 存在AI业务总结则展示解读文本 if result[summary]: st.markdown(### 业务总结) st.info(result[summary]) # 无匹配订单提示 else: st.info(未查询到匹配的数据) # 页面2SQL性能调优分析页面 else: st.header( SQL 性能调优分析) # 输入框接收用户待优化SELECT语句 raw_sql st.text_area(请输入待分析的 SQL 语句, height200) # 点击分析按钮执行调优流程 if st.button( 开始分析, typeprimary): input_trim raw_sql.strip() # 校验1空输入拦截 if not input_trim: st.warning(请输入有效的 SQL 语句后再提交) # 校验2必须是SELECT语句禁止其他类型SQL elif not re.match(r(?i)^\s*SELECT\s, input_trim): st.warning(此处请输入待分析的 SELECT SQL 语句请勿输入自然语言描述。如需自然语言转 SQL请切换到「数据查询与总结」页面。) # 校验通过执行调优分析 else: with st.spinner(正在获取执行计划并分析...): # 调用main封装的调优函数 result sql_tune_analyze(raw_sql) # 分析失败展示错误 if not result[success]: st.error(f分析失败{result[error]}) # 分析成功展示执行计划表格AI优化建议 else: st.success(执行计划获取成功) st.dataframe(result[plan_rows], use_container_widthTrue) st.markdown(### 调优建议) st.markdown(result[suggestion])7.2.4. 创建 systemd 后台常驻服务vim /etc/systemd/system/mysql-ai-web.service启动服务[rootyaoguoqiang ~]# systemctl daemon-reload [rootyaoguoqiang ~]# systemctl enable --now mysql-ai-web
返回列表